mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2025-01-19 05:33:44 +01:00
Change how DownloadProgressTracker waits for progress to avoid possible deadlocks.
This commit is contained in:
parent
b25899de58
commit
2967e07c8b
@ -17,11 +17,13 @@
|
||||
|
||||
package org.bitcoinj.core;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.common.util.concurrent.SettableFuture;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
/**
|
||||
* <p>An implementation of {@link AbstractPeerEventListener} that listens to chain download events and tracks progress
|
||||
@ -32,12 +34,13 @@ public class DownloadProgressTracker extends AbstractPeerEventListener {
|
||||
private static final Logger log = LoggerFactory.getLogger(DownloadProgressTracker.class);
|
||||
private int originalBlocksLeft = -1;
|
||||
private int lastPercent = 0;
|
||||
private Semaphore done = new Semaphore(0);
|
||||
private SettableFuture<Long> future = SettableFuture.create();
|
||||
private boolean caughtUp = false;
|
||||
|
||||
@Override
|
||||
public void onChainDownloadStarted(Peer peer, int blocksLeft) {
|
||||
startDownload(blocksLeft);
|
||||
if (blocksLeft > 0 && originalBlocksLeft == -1)
|
||||
startDownload(blocksLeft);
|
||||
// Only mark this the first time, because this method can be called more than once during a chain download
|
||||
// if we switch peers during it.
|
||||
if (originalBlocksLeft == -1)
|
||||
@ -46,7 +49,7 @@ public class DownloadProgressTracker extends AbstractPeerEventListener {
|
||||
log.info("Chain download switched to {}", peer);
|
||||
if (blocksLeft == 0) {
|
||||
doneDownload();
|
||||
done.release();
|
||||
future.set(peer.getBestHeight());
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,7 +61,7 @@ public class DownloadProgressTracker extends AbstractPeerEventListener {
|
||||
if (blocksLeft == 0) {
|
||||
caughtUp = true;
|
||||
doneDownload();
|
||||
done.release();
|
||||
future.set(peer.getBestHeight());
|
||||
}
|
||||
|
||||
if (blocksLeft < 0 || originalBlocksLeft <= 0)
|
||||
@ -88,10 +91,8 @@ public class DownloadProgressTracker extends AbstractPeerEventListener {
|
||||
* @param blocks the number of blocks to download, estimated
|
||||
*/
|
||||
protected void startDownload(int blocks) {
|
||||
if (blocks > 0 && originalBlocksLeft == -1)
|
||||
log.info("Downloading block chain of size " + blocks + ". " +
|
||||
(blocks > 1000 ? "This may take a while." : ""));
|
||||
|
||||
log.info("Downloading block chain of size " + blocks + ". " +
|
||||
(blocks > 1000 ? "This may take a while." : ""));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -104,6 +105,18 @@ public class DownloadProgressTracker extends AbstractPeerEventListener {
|
||||
* Wait for the chain to be downloaded.
|
||||
*/
|
||||
public void await() throws InterruptedException {
|
||||
done.acquire();
|
||||
try {
|
||||
future.get();
|
||||
} catch (ExecutionException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a listenable future that completes with the height of the best chain (as reported by the peer) once chain
|
||||
* download seems to be finished.
|
||||
*/
|
||||
public ListenableFuture<Long> getFuture() {
|
||||
return future;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user