Register Chronicle Map's randomAccessFile cleaner only after all creation/recovery procedures complete, to avoid double release

This commit is contained in:
leventov
2016-02-09 14:57:44 +07:00
parent 001b710084
commit e2ec9db371
2 changed files with 16 additions and 10 deletions
@@ -129,7 +129,7 @@ public abstract class VanillaChronicleHash<K,
// Bytes Store (essentially, the base address) and serialization-dependent offsets
private transient File file;
private transient RandomAccessFile raf;
private transient Cleaner releaseRaf;
private transient Cleaner rafCleaner;
protected transient BytesStore bs;
public static class TierBulkData {
@@ -459,13 +459,16 @@ public abstract class VanillaChronicleHash<K,
private void setFile(File file, RandomAccessFile raf) {
this.file = file;
this.raf = raf;
this.releaseRaf = Cleaner.create(this, new RafRelease(file));
}
private static class RafRelease implements Runnable {
public void registerRafReleaser() {
this.rafCleaner = Cleaner.create(this, new RafReleaser(file));
}
private static class RafReleaser implements Runnable {
final File file;
private RafRelease(File file) {
private RafReleaser(File file) {
this.file = file;
}
@@ -631,8 +634,8 @@ public abstract class VanillaChronicleHash<K,
assert bulkData.bytesStore.refCount() == 0;
}
}
if (releaseRaf != null)
releaseRaf.clean();
if (rafCleaner != null)
rafCleaner.clean();
}
@Override
@@ -1432,7 +1432,7 @@ public final class ChronicleMapBuilder<K, V> implements
//noinspection ResultOfMethodCallIgnored
file.createNewFile();
}
ChronicleMap<K, V> result = null;
VanillaChronicleMap<K, V, ?> result = null;
RandomAccessFile raf = CanonicalRandomAccessFiles.acquire(file);
try {
if (raf.length() > 0)
@@ -1461,8 +1461,11 @@ public final class ChronicleMapBuilder<K, V> implements
return result = openWithExistingFile(file, raf, recover, overrideBuilderConfig);
}
} finally {
if (result == null)
if (result != null) {
result.registerRafReleaser();
} else {
CanonicalRandomAccessFiles.release(file);
}
}
}
@@ -1558,7 +1561,7 @@ public final class ChronicleMapBuilder<K, V> implements
return LongHashFunction.xx_r39().hashBytes(headerBuffer, SIZE_WORD_OFFSET, headerSize + 4);
}
private ChronicleMap<K, V> createWithNewFile(
private VanillaChronicleMap<K, V, ?> createWithNewFile(
VanillaChronicleMap<K, V, ?> map, File file, RandomAccessFile raf,
ByteBuffer headerBuffer, int headerSize) throws IOException {
FileChannel fileChannel = raf.getChannel();
@@ -1569,7 +1572,7 @@ public final class ChronicleMapBuilder<K, V> implements
return map;
}
private ChronicleMap<K, V> openWithExistingFile(
private VanillaChronicleMap<K, V, ?> openWithExistingFile(
File file, RandomAccessFile raf, boolean recover, boolean overrideBuilderConfig)
throws IOException {
try {