From 66b02c93e69cfeaec6e7fa19a03bfb2649025a56 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 13 Sep 2012 14:33:52 +0200 Subject: Move external block import to separate thread --- src/main.cpp | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 5 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 28bf01a8cb..a5179b6527 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -38,6 +38,7 @@ CBigNum bnBestInvalidWork = 0; uint256 hashBestChain = 0; CBlockIndex* pindexBest = NULL; int64 nTimeBestReceived = 0; +bool fImporting = false; CMedianFilter cPeerBlockCounts(5, 0); // Amount of blocks that other nodes claim to have @@ -2251,7 +2252,6 @@ bool LoadExternalBlockFile(FILE* fileIn) int nLoaded = 0; { - LOCK(cs_main); try { CAutoFile blkdat(fileIn, SER_DISK, CLIENT_VERSION); unsigned int nPos = 0; @@ -2288,6 +2288,7 @@ bool LoadExternalBlockFile(FILE* fileIn) { CBlock block; blkdat >> block; + LOCK(cs_main); if (ProcessBlock(NULL,&block)) { nLoaded++; @@ -2305,6 +2306,54 @@ bool LoadExternalBlockFile(FILE* fileIn) return nLoaded > 0; } +struct CImportingNow +{ + CImportingNow() { + assert(fImporting == false); + fImporting = true; + } + + ~CImportingNow() { + assert(fImporting == true); + fImporting = false; + } +}; + +void ThreadImport(void *data) { + std::vector *vFiles = reinterpret_cast*>(data); + + RenameThread("bitcoin-loadblk"); + + CImportingNow imp; + vnThreadsRunning[THREAD_IMPORT]++; + + // -loadblock= + uiInterface.InitMessage(_("Starting block import...")); + BOOST_FOREACH(boost::filesystem::path &path, *vFiles) { + FILE *file = fopen(path.string().c_str(), "rb"); + if (file) + LoadExternalBlockFile(file); + } + + // hardcoded $DATADIR/bootstrap.dat + filesystem::path pathBootstrap = GetDataDir() / "bootstrap.dat"; + if (filesystem::exists(pathBootstrap)) { + uiInterface.InitMessage(_("Importing bootstrap blockchain data file.")); + + FILE *file = fopen(pathBootstrap.string().c_str(), "rb"); + if (file) { + filesystem::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old"; + LoadExternalBlockFile(file); + RenameOver(pathBootstrap, pathBootstrapOld); + } + } + + delete vFiles; + + vnThreadsRunning[THREAD_IMPORT]--; +} + + @@ -2512,7 +2561,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) // Ask the first connected node for block updates static int nAskedForBlocks = 0; - if (!pfrom->fClient && !pfrom->fOneShot && + if (!pfrom->fClient && !pfrom->fOneShot && !fImporting && (pfrom->nStartingHeight > (nBestHeight - 144)) && (pfrom->nVersion < NOBLKS_VERSION_START || pfrom->nVersion >= NOBLKS_VERSION_END) && @@ -2649,9 +2698,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) if (fDebug) printf(" got inventory: %s %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new"); - if (!fAlreadyHave) - pfrom->AskFor(inv); - else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) { + if (!fAlreadyHave) { + if (!fImporting) + pfrom->AskFor(inv); + } else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) { pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(mapOrphanBlocks[inv.hash])); } else if (nInv == nLastBlock) { // In case we are on a very long side-chain, it is possible that we already have -- cgit v1.2.3