mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-08-01 12:31:23 +00:00
Change how DownloadProgressTracker waits for progress to avoid possible deadlocks.
This commit is contained in:
@@ -17,11 +17,13 @@
|
|||||||
|
|
||||||
package org.bitcoinj.core;
|
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.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.Date;
|
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
|
* <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 static final Logger log = LoggerFactory.getLogger(DownloadProgressTracker.class);
|
||||||
private int originalBlocksLeft = -1;
|
private int originalBlocksLeft = -1;
|
||||||
private int lastPercent = 0;
|
private int lastPercent = 0;
|
||||||
private Semaphore done = new Semaphore(0);
|
private SettableFuture<Long> future = SettableFuture.create();
|
||||||
private boolean caughtUp = false;
|
private boolean caughtUp = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onChainDownloadStarted(Peer peer, int blocksLeft) {
|
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
|
// 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 we switch peers during it.
|
||||||
if (originalBlocksLeft == -1)
|
if (originalBlocksLeft == -1)
|
||||||
@@ -46,7 +49,7 @@ public class DownloadProgressTracker extends AbstractPeerEventListener {
|
|||||||
log.info("Chain download switched to {}", peer);
|
log.info("Chain download switched to {}", peer);
|
||||||
if (blocksLeft == 0) {
|
if (blocksLeft == 0) {
|
||||||
doneDownload();
|
doneDownload();
|
||||||
done.release();
|
future.set(peer.getBestHeight());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +61,7 @@ public class DownloadProgressTracker extends AbstractPeerEventListener {
|
|||||||
if (blocksLeft == 0) {
|
if (blocksLeft == 0) {
|
||||||
caughtUp = true;
|
caughtUp = true;
|
||||||
doneDownload();
|
doneDownload();
|
||||||
done.release();
|
future.set(peer.getBestHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blocksLeft < 0 || originalBlocksLeft <= 0)
|
if (blocksLeft < 0 || originalBlocksLeft <= 0)
|
||||||
@@ -88,10 +91,8 @@ public class DownloadProgressTracker extends AbstractPeerEventListener {
|
|||||||
* @param blocks the number of blocks to download, estimated
|
* @param blocks the number of blocks to download, estimated
|
||||||
*/
|
*/
|
||||||
protected void startDownload(int blocks) {
|
protected void startDownload(int blocks) {
|
||||||
if (blocks > 0 && originalBlocksLeft == -1)
|
log.info("Downloading block chain of size " + blocks + ". " +
|
||||||
log.info("Downloading block chain of size " + blocks + ". " +
|
(blocks > 1000 ? "This may take a while." : ""));
|
||||||
(blocks > 1000 ? "This may take a while." : ""));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -104,6 +105,18 @@ public class DownloadProgressTracker extends AbstractPeerEventListener {
|
|||||||
* Wait for the chain to be downloaded.
|
* Wait for the chain to be downloaded.
|
||||||
*/
|
*/
|
||||||
public void await() throws InterruptedException {
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user