From c8117b95027400f363326fedceb59b74a003ba58 Mon Sep 17 00:00:00 2001 From: Ivan Rakov Date: Wed, 16 Jun 2021 18:16:04 +0300 Subject: [PATCH] dirtyfix. --- .../openhft/chronicle/map/FileLockUtil.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/main/java/net/openhft/chronicle/map/FileLockUtil.java b/src/main/java/net/openhft/chronicle/map/FileLockUtil.java index 161877f77..a29c27c8e 100644 --- a/src/main/java/net/openhft/chronicle/map/FileLockUtil.java +++ b/src/main/java/net/openhft/chronicle/map/FileLockUtil.java @@ -90,6 +90,46 @@ public final class FileLockUtil { printWarningTheFirstTime(); } + /** + * Executes a closure under exclusive file lock. + * If USE_LOCKING is false, provides synchronization only within local JVM. + * + * @param fileIOAction Closure to run, can throw {@link IOException}s. + */ + public static boolean tryRunExclusively(@NotNull final File canonicalFile, + @NotNull final FileChannel fileChannel, + @NotNull final FileIOAction fileIOAction) { + FILE_LOCKS.compute(canonicalFile, (f, flr) -> { + if (flr != null) + throw new ChronicleFileLockException("A file lock instance already exists for the file " + canonicalFile); + + try { + if (USE_LOCKING) { + do { + try (FileLock ignored = fileChannel.tryLock()) { + if (ignored == null) { + Jvm.pause(10); + + continue; + } + + fileIOAction.fileIOAction(); + + break; + } + } while (true); + } else { + fileIOAction.fileIOAction(); + } + + return null; + } catch (Exception e) { + throw Jvm.rethrow(e); + } + } + ); + } + /** * Executes a closure under exclusive file lock. * If USE_LOCKING is false, provides synchronization only within local JVM.