3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-11 17:55:53 +00:00

SPVBlockStore: add a workaround for a Windows specific bug. We should scrap the use of mmap in this class if we can, too many platforms have odd bugs and glitches with it.

This commit is contained in:
Mike Hearn 2015-01-27 18:40:58 +01:00
parent c2c3b715f3
commit 07d85f24ad
2 changed files with 38 additions and 19 deletions

View File

@ -17,26 +17,19 @@
package org.bitcoinj.store;
import org.bitcoinj.core.*;
import org.bitcoinj.utils.Threading;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.bitcoinj.utils.*;
import org.slf4j.*;
import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;
import javax.annotation.*;
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.util.*;
import java.util.concurrent.locks.*;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Preconditions.*;
// TODO: Lose the mmap in this class. There are too many platform bugs that require odd workarounds.
/**
* An SPVBlockStore holds a limited number of block headers in a memory mapped ring buffer. With such a store, you
@ -269,9 +262,12 @@ public class SPVBlockStore implements BlockStore {
public void close() throws BlockStoreException {
try {
buffer.force();
if (System.getProperty("os.name").toLowerCase().contains("win")) {
log.info("Windows mmap hack: Forcing buffer cleaning");
WindowsMMapHack.forceRelease(buffer);
}
buffer = null; // Allow it to be GCd and the underlying file mapping to go away.
randomAccessFile.close();
fileLock.release();
} catch (IOException e) {
throw new BlockStoreException(e);
}

View File

@ -0,0 +1,23 @@
package org.bitcoinj.store;
import sun.misc.*;
import sun.nio.ch.*;
import java.nio.*;
/**
* <p>This class knows how to force an mmap'd ByteBuffer to reliquish its file handles before it becomes garbage collected,
* by exploiting implementation details of the HotSpot JVM implementation.</p>
*
* <p>This is required on Windows because otherwise an attempt to delete a file that is still mmapped will fail. This can
* happen when a user requests a "restore from seed" function, which involves deleting and recreating the chain file.
* At some point we should stop using mmap in SPVBlockStore and we can then delete this class.</p>
*
* <p>It is a separate class to avoid hitting unknown imports when running on other JVMs.</p>
*/
public class WindowsMMapHack {
public static void forceRelease(MappedByteBuffer buffer) {
Cleaner cleaner = ((DirectBuffer) buffer).cleaner();
if (cleaner != null) cleaner.clean();
}
}