diff --git a/src/main/java/net/openhft/chronicle/hash/impl/util/CanonicalRandomAccessFiles.java b/src/main/java/net/openhft/chronicle/hash/impl/util/CanonicalRandomAccessFiles.java index 9c801ea4f..7ce438798 100644 --- a/src/main/java/net/openhft/chronicle/hash/impl/util/CanonicalRandomAccessFiles.java +++ b/src/main/java/net/openhft/chronicle/hash/impl/util/CanonicalRandomAccessFiles.java @@ -18,38 +18,71 @@ package net.openhft.chronicle.hash.impl.util; import net.openhft.chronicle.core.CleaningRandomAccessFile; import net.openhft.chronicle.core.Jvm; +import net.openhft.chronicle.core.OS; +import net.openhft.chronicle.hash.ChronicleFileLockException; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; +import java.nio.channels.FileChannel; +import java.nio.channels.FileLock; +import java.nio.channels.OverlappingFileLockException; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; public final class CanonicalRandomAccessFiles { + /** + * Java file locks are maintained on a per JVM basis. So we need to manage them. + */ + private static final String DISABLE_LOCKING = "chronicle.map.disable.locking"; + private static final boolean USE_EXCLUSIVE_LOCKING = !Jvm.getBoolean(DISABLE_LOCKING); + private static final boolean USE_SHARED_LOCKING = !OS.isWindows() && !Jvm.getBoolean(DISABLE_LOCKING) && + !"shared".equalsIgnoreCase(System.getProperty(DISABLE_LOCKING)); + private static final AtomicBoolean LOCK_WARNING_PRINTED = new AtomicBoolean(); private static final ConcurrentHashMap CANONICAL_RAFS = new ConcurrentHashMap<>(); private CanonicalRandomAccessFiles() { } public static RandomAccessFile acquire(@NotNull final File file) throws FileNotFoundException { - return CANONICAL_RAFS.compute(file, (f, ref) -> { - if (ref == null) { - try { - return new RafReference(new CleaningRandomAccessFile(f, "rw")); - } catch (FileNotFoundException e) { - throw Jvm.rethrow(e); - } - } else { - ref.refCount++; - return ref; - } - }).raf; + return acquire0(file, (ref) -> {}).raf; } - public static void release(@NotNull final File file) throws IOException { - CANONICAL_RAFS.computeIfPresent(file, (f, ref) -> { + private static RafReference acquire0(@NotNull final File file, Consumer action) { + return CANONICAL_RAFS.compute(file, (f, ref) -> { + while (ref != null) { + try { + ref.raf.length(); + } catch (IOException e) { + // File is closed by interrupt; + break; + } + + ref.refCount++; + action.accept(ref); + return ref; + } + + try { + return new RafReference(new CleaningRandomAccessFile(f, "rw")); + } catch (FileNotFoundException e) { + throw Jvm.rethrow(e); + } + }); + } + + public static void release(@NotNull final File file) { + release0(file, (ref) -> {}); + } + + private static RafReference release0(@NotNull final File file, Consumer action) { + return CANONICAL_RAFS.computeIfPresent(file, (f, ref) -> { + action.accept(ref); if (--ref.refCount == 0) { try { ref.raf.close(); @@ -63,15 +96,234 @@ public final class CanonicalRandomAccessFiles { }); } + public static void acquireSharedFileLock(@NotNull final File canonicalFile, @NotNull final FileChannel channel) { + if (USE_SHARED_LOCKING) + acquire0(canonicalFile, (rafReference) -> { + try { + if (rafReference.lockRef == null) + rafReference.lockRef = new FileLockReference(channel.lock(0, Long.MAX_VALUE, true)); + else { + if (!rafReference.lockRef.fileLock.isShared()) { + throw newUnableToAcquireSharedFileLockException(canonicalFile, null); + } + rafReference.lockRef.reserve(); + } + } catch (IOException | IllegalStateException e) { + throw newUnableToAcquireSharedFileLockException(canonicalFile, e); + } + }); + else + printWarningTheFirstTime(); + } + + public static void acquireExclusiveFileLock(@NotNull final File canonicalFile, @NotNull final FileChannel channel) { + if (USE_EXCLUSIVE_LOCKING) + acquire0(canonicalFile, (rafReference) -> { + if (rafReference.lockRef == null) { + try { + final FileLock fileLock = channel.lock(0, Long.MAX_VALUE, false); + rafReference.lockRef = new FileLockReference(fileLock); + } catch (IOException e) { + throw newUnableToAcquireExclusiveFileLockException(canonicalFile, e); + } + } else { + throw newUnableToAcquireExclusiveFileLockException(canonicalFile, null); + } + }); + else + printWarningTheFirstTime(); + } + + public static void releaseSharedFileLock(@NotNull final File canonicalFile) { + if (USE_SHARED_LOCKING) + releaseFileLock0(canonicalFile); + else + printWarningTheFirstTime(); + } + + public static void releaseExclusiveFileLock(@NotNull final File canonicalFile) { + if (USE_EXCLUSIVE_LOCKING) + releaseFileLock0(canonicalFile); + else + printWarningTheFirstTime(); + } + + private static void releaseFileLock0(@NotNull File canonicalFile) { + release0(canonicalFile, (rafReference) -> { + if (rafReference.lockRef == null) + throw new ChronicleFileLockException("Trying to release lock on file " + canonicalFile + " that did not exist"); + else { + final int cnt = rafReference.lockRef.release(); + if (cnt == 0) + rafReference.lockRef = null; + } + }); + } + + /** + * Tries to execute 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. + * @return true if the lock was successfully acquired and IO action was executed, false otherwise. + */ + public static boolean tryRunExclusively(@NotNull final File canonicalFile, + @NotNull final FileChannel fileChannel, + @NotNull final FileIOAction fileIOAction) { + AtomicBoolean locked = new AtomicBoolean(false); + + acquire0(canonicalFile, (rafReference) -> { + if (rafReference.lockRef != null) + return; + + try { + if (USE_EXCLUSIVE_LOCKING) { + try (FileLock ignored = fileChannel.tryLock()) { + if (ignored == null) { + rafReference.lockRef = null; + + return; + } + + fileIOAction.fileIOAction(); + + locked.set(true); + } + catch (OverlappingFileLockException ignored) { + // File lock is being held by this JVM, unsuccessful attempt. + } + } else { + fileIOAction.fileIOAction(); + + locked.set(true); + } + + rafReference.lockRef = null; + } catch (Exception e) { + throw Jvm.rethrow(e); + } + } + ); + + release(canonicalFile); + + return locked.get(); + } + + /** + * 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 void runExclusively(@NotNull final File canonicalFile, + @NotNull final FileChannel fileChannel, + @NotNull final FileIOAction fileIOAction) { + acquire0(canonicalFile, (rafReference) -> { + if (rafReference.lockRef != null) + throw new ChronicleFileLockException("A file lock instance already exists for the file " + canonicalFile); + + try { + if (USE_EXCLUSIVE_LOCKING) { + try (FileLock ignored = fileChannel.lock()) { + fileIOAction.fileIOAction(); + } + } else { + fileIOAction.fileIOAction(); + } + } catch (Exception e) { + throw Jvm.rethrow(e); + } + }); + } + + static void dump() { + System.out.println(CANONICAL_RAFS); + } + + private static ChronicleFileLockException newUnableToAcquireSharedFileLockException(@NotNull final File canonicalFile, @Nullable final Exception e) { + return new ChronicleFileLockException("Unable to acquire a shared file lock for " + canonicalFile + ". " + + "Make sure another process is not recovering the map.", e); + } + + private static ChronicleFileLockException newUnableToAcquireExclusiveFileLockException(@NotNull final File canonicalFile, @Nullable final Exception e) { + return new ChronicleFileLockException("Unable to acquire an exclusive file lock for " + canonicalFile + ". " + + "Make sure no other process is using the map.", e); + } + + private static void printWarningTheFirstTime() { + if (LOCK_WARNING_PRINTED.compareAndSet(false, true)) { + Jvm.warn().on(CanonicalRandomAccessFiles.class, "File locking is disabled or not supported on this platform (" + System.getProperty("os.name") + "). " + + "Make sure you are not running ChronicleMapBuilder::*recover* methods when other processes or threads have the mapped file open!"); + } + } + + // This class is not thread-safe but instances + // are protected by means of the FILE_LOCKS map + public static final class FileLockReference { + private final FileLock fileLock; + private int refCount; + + FileLockReference(@NotNull final FileLock fileLock) { + this.fileLock = fileLock; + refCount = 1; + } + + int reserve() { + if (refCount == 0) + throw new IllegalStateException("Ref counter previously released"); + return ++refCount; + } + + int release() { + final int cnt = --refCount; + if (cnt == 0) { + try { + fileLock.release(); + } catch (IOException e) { + throw new ChronicleFileLockException(e); + } + } + if (cnt < 0) + throw new IllegalStateException("Ref counter was " + cnt); + + return cnt; + } + + @Override + public String toString() { + return "FileLockReference{" + + "fileLock=" + fileLock + + ", refCount=" + refCount + + '}'; + } + } + + @FunctionalInterface + public interface FileIOAction { + void fileIOAction() throws IOException; + } + // This class is not thread-safe but instances // are protected by means of the CANONICAL_RAFS map private static final class RafReference { private final RandomAccessFile raf; + private FileLockReference lockRef; private int refCount; RafReference(@NotNull final RandomAccessFile raf) { this.raf = raf; + this.lockRef = null; refCount = 1; } + + @Override + public String toString() { + return "RafReference{" + + "raf=" + raf + + ", lockRef=" + lockRef + + ", refCount=" + refCount + + '}'; + } } } diff --git a/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java index eb3b9eb7a..6093a06ea 100644 --- a/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java +++ b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java @@ -1713,7 +1713,7 @@ public final class ChronicleMapBuilder implements TimingPauser pauser = Pauser.balanced(); while (raf.length() == 0) { - final boolean locked = FileLockUtil.tryRunExclusively(canonicalFile, fileChannel, () -> { + final boolean locked = CanonicalRandomAccessFiles.tryRunExclusively(canonicalFile, fileChannel, () -> { // Double-checked locking if (raf.length() == 0) { map.set(newMap()); @@ -1840,8 +1840,8 @@ public final class ChronicleMapBuilder implements map.initBeforeMapping(canonicalFile, raf, headerBuffer.limit(), false); map.createMappedStoreAndSegments(resources); - FileLockUtil.acquireSharedFileLock(canonicalFile, raf.getChannel()); - map.addCloseable(() -> FileLockUtil.releaseSharedFileLock(canonicalFile)); + CanonicalRandomAccessFiles.acquireSharedFileLock(canonicalFile, raf.getChannel()); + map.addCloseable(() -> CanonicalRandomAccessFiles.releaseSharedFileLock(canonicalFile)); commitChronicleMapReady(map, raf, headerBuffer, headerSize); return map; } @@ -1907,22 +1907,22 @@ public final class ChronicleMapBuilder implements map.initTransientsFromBuilder(this); if (!recover) { map.createMappedStoreAndSegments(resources); - FileLockUtil.acquireSharedFileLock(file, raf.getChannel()); + CanonicalRandomAccessFiles.acquireSharedFileLock(file, raf.getChannel()); } else { if (!headerWritten) writeNotComplete(fileChannel, headerBuffer, headerSize); try { - FileLockUtil.acquireExclusiveFileLock(file, raf.getChannel()); + CanonicalRandomAccessFiles.acquireExclusiveFileLock(file, raf.getChannel()); map.recover(resources, corruptionListener, corruption); } finally { - FileLockUtil.releaseExclusiveFileLock(file); + CanonicalRandomAccessFiles.releaseExclusiveFileLock(file); } // We are ready with exclusive access. // Demote the lock from exclusive to shared - FileLockUtil.acquireSharedFileLock(file, fileChannel); + CanonicalRandomAccessFiles.acquireSharedFileLock(file, fileChannel); commitChronicleMapReady(map, raf, headerBuffer, headerSize); } - map.addCloseable(() -> FileLockUtil.releaseSharedFileLock(file)); + map.addCloseable(() -> CanonicalRandomAccessFiles.releaseSharedFileLock(file)); if (MAP_CREATION_DEBUG) { Jvm.warn().on(getClass(), " Created map [name=" + map.name() + ", size=" + map.longSize() + "] from file [canonizedMapDataFile=" + diff --git a/src/main/java/net/openhft/chronicle/map/FileLockUtil.java b/src/main/java/net/openhft/chronicle/map/FileLockUtil.java deleted file mode 100644 index cdbd20c42..000000000 --- a/src/main/java/net/openhft/chronicle/map/FileLockUtil.java +++ /dev/null @@ -1,257 +0,0 @@ -package net.openhft.chronicle.map; - -import net.openhft.chronicle.core.Jvm; -import net.openhft.chronicle.core.OS; -import net.openhft.chronicle.hash.ChronicleFileLockException; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.io.File; -import java.io.IOException; -import java.nio.channels.FileChannel; -import java.nio.channels.FileLock; -import java.nio.channels.OverlappingFileLockException; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicBoolean; - -public final class FileLockUtil { - - /** - * Java file locks are maintained on a per JVM basis. So we need to manage them. - */ - private static final String DISABLE_LOCKING = "chronicle.map.disable.locking"; - private static final ConcurrentHashMap FILE_LOCKS = new ConcurrentHashMap<>(); - private static final boolean USE_EXCLUSIVE_LOCKING = !Jvm.getBoolean(DISABLE_LOCKING); - private static final boolean USE_SHARED_LOCKING = !OS.isWindows() && !Jvm.getBoolean(DISABLE_LOCKING) && - !"shared".equalsIgnoreCase(System.getProperty(DISABLE_LOCKING)); - private static final AtomicBoolean LOCK_WARNING_PRINTED = new AtomicBoolean(); - - private FileLockUtil() { - } - - public static void acquireSharedFileLock(@NotNull final File canonicalFile, @NotNull final FileChannel channel) { - if (USE_SHARED_LOCKING) - FILE_LOCKS.compute(canonicalFile, (f, flr) -> - { - try { - if (flr == null) - return new FileLockReference(channel.lock(0, Long.MAX_VALUE, true)); - else { - if (!flr.fileLock.isShared()) { - throw newUnableToAcquireSharedFileLockException(canonicalFile, null); - } - flr.reserve(); - return flr; // keep the old one - } - } catch (IOException | IllegalStateException e) { - throw newUnableToAcquireSharedFileLockException(canonicalFile, e); - } - } - ); - else - printWarningTheFirstTime(); - - } - - public static void acquireExclusiveFileLock(@NotNull final File canonicalFile, @NotNull final FileChannel channel) { - if (USE_EXCLUSIVE_LOCKING) - FILE_LOCKS.compute(canonicalFile, (f, flr) -> - { - if (flr == null) { - try { - final FileLock fileLock = channel.lock(0, Long.MAX_VALUE, false); - return new FileLockReference(fileLock); - } catch (IOException e) { - throw newUnableToAcquireExclusiveFileLockException(canonicalFile, e); - } - } else { - throw newUnableToAcquireExclusiveFileLockException(canonicalFile, null); - } - - } - ); - else - printWarningTheFirstTime(); - } - - public static void releaseSharedFileLock(@NotNull final File canonicalFile) { - if (USE_SHARED_LOCKING) - releaseFileLock0(canonicalFile); - else - printWarningTheFirstTime(); - } - - public static void releaseExclusiveFileLock(@NotNull final File canonicalFile) { - if (USE_EXCLUSIVE_LOCKING) - releaseFileLock0(canonicalFile); - else - printWarningTheFirstTime(); - } - - /** - * @deprecated Use {@link #releaseExclusiveFileLock(File)} or {@link #releaseSharedFileLock(File)} instead. - */ - @Deprecated - public static void releaseFileLock(@NotNull final File canonicalFile) { - releaseExclusiveFileLock(canonicalFile); - } - - private static void releaseFileLock0(@NotNull File canonicalFile) { - FILE_LOCKS.compute(canonicalFile, (f, flr) -> - { - if (flr == null) - throw new ChronicleFileLockException("Trying to release lock on file " + canonicalFile + " that did not exist"); - else { - final int cnt = flr.release(); - if (cnt == 0) - return null; // Remove the old one - else - return flr; - } - } - - ); - } - - /** - * Tries to execute 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. - * @return true if the lock was successfully acquired and IO action was executed, false otherwise. - */ - public static boolean tryRunExclusively(@NotNull final File canonicalFile, - @NotNull final FileChannel fileChannel, - @NotNull final FileIOAction fileIOAction) { - AtomicBoolean locked = new AtomicBoolean(false); - - FILE_LOCKS.compute(canonicalFile, (f, flr) -> { - if (flr != null) - return flr; - - try { - if (USE_EXCLUSIVE_LOCKING) { - try (FileLock ignored = fileChannel.tryLock()) { - if (ignored == null) - return null; - - fileIOAction.fileIOAction(); - - locked.set(true); - } - catch (OverlappingFileLockException ignored) { - // File lock is being held by this JVM, unsuccessful attempt. - } - } else { - fileIOAction.fileIOAction(); - - locked.set(true); - } - - return null; - } catch (Exception e) { - throw Jvm.rethrow(e); - } - } - ); - - return locked.get(); - } - - /** - * 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 void runExclusively(@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_EXCLUSIVE_LOCKING) { - try (FileLock ignored = fileChannel.lock()) { - fileIOAction.fileIOAction(); - } - } else { - fileIOAction.fileIOAction(); - } - - return null; - } catch (Exception e) { - throw Jvm.rethrow(e); - } - } - ); - } - - static void dump() { - System.out.println(FILE_LOCKS); - } - - private static ChronicleFileLockException newUnableToAcquireSharedFileLockException(@NotNull final File canonicalFile, @Nullable final Exception e) { - return new ChronicleFileLockException("Unable to acquire a shared file lock for " + canonicalFile + ". " + - "Make sure another process is not recovering the map.", e); - } - - private static ChronicleFileLockException newUnableToAcquireExclusiveFileLockException(@NotNull final File canonicalFile, @Nullable final Exception e) { - return new ChronicleFileLockException("Unable to acquire an exclusive file lock for " + canonicalFile + ". " + - "Make sure no other process is using the map.", e); - } - - private static void printWarningTheFirstTime() { - if (LOCK_WARNING_PRINTED.compareAndSet(false, true)) { - Jvm.warn().on(FileLockUtil.class, "File locking is disabled or not supported on this platform (" + System.getProperty("os.name") + "). " + - "Make sure you are not running ChronicleMapBuilder::*recover* methods when other processes or threads have the mapped file open!"); - } - } - - // This class is not thread-safe but instances - // are protected by means of the FILE_LOCKS map - private static final class FileLockReference { - private final FileLock fileLock; - private int refCount; - - FileLockReference(@NotNull final FileLock fileLock) { - this.fileLock = fileLock; - refCount = 1; - } - - int reserve() { - if (refCount == 0) - throw new IllegalStateException("Ref counter previously released"); - return ++refCount; - } - - int release() { - final int cnt = --refCount; - if (cnt == 0) { - try { - fileLock.release(); - } catch (IOException e) { - throw new ChronicleFileLockException(e); - } - } - if (cnt < 0) - throw new IllegalStateException("Ref counter was " + cnt); - - return cnt; - } - - @Override - public String toString() { - return "FileLockReference{" + - "fileLock=" + fileLock + - ", refCount=" + refCount + - '}'; - } - } - - @FunctionalInterface - interface FileIOAction { - void fileIOAction() throws IOException; - } -} \ No newline at end of file diff --git a/src/test/java/net/openhft/chronicle/map/FileLockUtilTest.java b/src/test/java/net/openhft/chronicle/map/FileLockUtilTest.java index 4820c46c5..046a773cf 100644 --- a/src/test/java/net/openhft/chronicle/map/FileLockUtilTest.java +++ b/src/test/java/net/openhft/chronicle/map/FileLockUtilTest.java @@ -39,78 +39,78 @@ public class FileLockUtilTest { @Test public void testShared() { if (!OS.isWindows()) { - FileLockUtil.acquireSharedFileLock(canonicalFile, fileChannel); - FileLockUtil.acquireSharedFileLock(canonicalFile, fileChannel); - FileLockUtil.releaseSharedFileLock(canonicalFile); - FileLockUtil.releaseSharedFileLock(canonicalFile); + CanonicalRandomAccessFiles.acquireSharedFileLock(canonicalFile, fileChannel); + CanonicalRandomAccessFiles.acquireSharedFileLock(canonicalFile, fileChannel); + CanonicalRandomAccessFiles.releaseSharedFileLock(canonicalFile); + CanonicalRandomAccessFiles.releaseSharedFileLock(canonicalFile); } } @Test public void testExclusiveNormalCase() { - FileLockUtil.acquireExclusiveFileLock(canonicalFile, fileChannel); - FileLockUtil.releaseExclusiveFileLock(canonicalFile); - FileLockUtil.acquireExclusiveFileLock(canonicalFile, fileChannel); - FileLockUtil.releaseExclusiveFileLock(canonicalFile); + CanonicalRandomAccessFiles.acquireExclusiveFileLock(canonicalFile, fileChannel); + CanonicalRandomAccessFiles.releaseExclusiveFileLock(canonicalFile); + CanonicalRandomAccessFiles.acquireExclusiveFileLock(canonicalFile, fileChannel); + CanonicalRandomAccessFiles.releaseExclusiveFileLock(canonicalFile); } @Test public void testTryExclusiveButWasShared() { if (!OS.isWindows()) { - FileLockUtil.acquireSharedFileLock(canonicalFile, fileChannel); + CanonicalRandomAccessFiles.acquireSharedFileLock(canonicalFile, fileChannel); try { - FileLockUtil.acquireExclusiveFileLock(canonicalFile, fileChannel); + CanonicalRandomAccessFiles.acquireExclusiveFileLock(canonicalFile, fileChannel); fail(); } catch (ChronicleFileLockException ignore) { } - FileLockUtil.releaseSharedFileLock(canonicalFile); + CanonicalRandomAccessFiles.releaseSharedFileLock(canonicalFile); } } @Test public void testTrySharedButWasExclusive() { if (!OS.isWindows()) { - FileLockUtil.acquireExclusiveFileLock(canonicalFile, fileChannel); + CanonicalRandomAccessFiles.acquireExclusiveFileLock(canonicalFile, fileChannel); try { - FileLockUtil.acquireSharedFileLock(canonicalFile, fileChannel); + CanonicalRandomAccessFiles.acquireSharedFileLock(canonicalFile, fileChannel); fail(); } catch (ChronicleFileLockException ignore) { } - FileLockUtil.releaseExclusiveFileLock(canonicalFile); + CanonicalRandomAccessFiles.releaseExclusiveFileLock(canonicalFile); } } @Test public void testComplicated() { if (!OS.isWindows()) { - FileLockUtil.acquireExclusiveFileLock(canonicalFile, fileChannel); - FileLockUtil.releaseExclusiveFileLock(canonicalFile); - FileLockUtil.acquireSharedFileLock(canonicalFile, fileChannel); - FileLockUtil.acquireSharedFileLock(canonicalFile, fileChannel); - FileLockUtil.releaseSharedFileLock(canonicalFile); - FileLockUtil.releaseSharedFileLock(canonicalFile); - FileLockUtil.acquireExclusiveFileLock(canonicalFile, fileChannel); - FileLockUtil.releaseExclusiveFileLock(canonicalFile); + CanonicalRandomAccessFiles.acquireExclusiveFileLock(canonicalFile, fileChannel); + CanonicalRandomAccessFiles.releaseExclusiveFileLock(canonicalFile); + CanonicalRandomAccessFiles.acquireSharedFileLock(canonicalFile, fileChannel); + CanonicalRandomAccessFiles.acquireSharedFileLock(canonicalFile, fileChannel); + CanonicalRandomAccessFiles.releaseSharedFileLock(canonicalFile); + CanonicalRandomAccessFiles.releaseSharedFileLock(canonicalFile); + CanonicalRandomAccessFiles.acquireExclusiveFileLock(canonicalFile, fileChannel); + CanonicalRandomAccessFiles.releaseExclusiveFileLock(canonicalFile); } } @Test public void testRunExclusively() { final AtomicInteger cnt = new AtomicInteger(); - FileLockUtil.runExclusively(canonicalFile, fileChannel, cnt::incrementAndGet); + CanonicalRandomAccessFiles.runExclusively(canonicalFile, fileChannel, cnt::incrementAndGet); assertEquals(1, cnt.get()); } @Test public void testRunExclusivelyButUsed() { if (!OS.isWindows()) { - FileLockUtil.acquireSharedFileLock(canonicalFile, fileChannel); + CanonicalRandomAccessFiles.acquireSharedFileLock(canonicalFile, fileChannel); try { - FileLockUtil.runExclusively(canonicalFile, fileChannel, () -> { + CanonicalRandomAccessFiles.runExclusively(canonicalFile, fileChannel, () -> { }); fail(); } catch (ChronicleFileLockException e) { - FileLockUtil.releaseSharedFileLock(canonicalFile); + CanonicalRandomAccessFiles.releaseSharedFileLock(canonicalFile); } } } @@ -118,16 +118,16 @@ public class FileLockUtilTest { @Test public void testTryRunExclusively() { if (!OS.isWindows()) { - FileLockUtil.acquireSharedFileLock(canonicalFile, fileChannel); + CanonicalRandomAccessFiles.acquireSharedFileLock(canonicalFile, fileChannel); - boolean lockedAndRun = FileLockUtil.tryRunExclusively(canonicalFile, fileChannel, () -> { + boolean lockedAndRun = CanonicalRandomAccessFiles.tryRunExclusively(canonicalFile, fileChannel, () -> { }); assertFalse(lockedAndRun); - FileLockUtil.releaseSharedFileLock(canonicalFile); + CanonicalRandomAccessFiles.releaseSharedFileLock(canonicalFile); - lockedAndRun = FileLockUtil.tryRunExclusively(canonicalFile, fileChannel, () -> { + lockedAndRun = CanonicalRandomAccessFiles.tryRunExclusively(canonicalFile, fileChannel, () -> { }); assertTrue(lockedAndRun);