diff options
-rw-r--r-- | src/bitcoinrpc.cpp | 2 | ||||
-rw-r--r-- | src/db.cpp | 5 | ||||
-rw-r--r-- | src/init.cpp | 10 | ||||
-rw-r--r-- | src/main.cpp | 5 | ||||
-rw-r--r-- | src/main.h | 2 | ||||
-rw-r--r-- | src/net.cpp | 50 | ||||
-rw-r--r-- | src/qt/qtipcserver.cpp | 2 | ||||
-rw-r--r-- | src/rpcmining.cpp | 4 | ||||
-rw-r--r-- | src/rpcwallet.cpp | 7 | ||||
-rw-r--r-- | src/util.cpp | 12 | ||||
-rw-r--r-- | src/util.h | 53 | ||||
-rw-r--r-- | src/wallet.cpp | 10 | ||||
-rw-r--r-- | src/wallet.h | 7 |
13 files changed, 67 insertions, 102 deletions
diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 2271ff07c4..84a6d6f896 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -697,7 +697,7 @@ static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor<Protocol, } // start HTTP client thread - else if (!CreateThread(ThreadRPCServer3, conn)) { + else if (!NewThread(ThreadRPCServer3, conn)) { printf("Failed to create RPC server client thread\n"); delete conn; } diff --git a/src/db.cpp b/src/db.cpp index 5671993d37..015e7ec2de 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -195,10 +195,7 @@ CDB::CDB(const char *pszFile, const char* pszMode) : { delete pdb; pdb = NULL; - { - LOCK(bitdb.cs_db); - --bitdb.mapFileUseCount[strFile]; - } + --bitdb.mapFileUseCount[strFile]; strFile = ""; throw runtime_error(strprintf("CDB() : can't open database file %s, error %d", pszFile, ret)); } diff --git a/src/init.cpp b/src/init.cpp index e7b1922dd0..6555f65a46 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -46,7 +46,7 @@ void StartShutdown() uiInterface.QueueShutdown(); #else // Without UI, Shutdown() can simply be started in a new thread - CreateThread(Shutdown, NULL); + NewThread(Shutdown, NULL); #endif } @@ -78,7 +78,7 @@ void Shutdown(void* parg) boost::filesystem::remove(GetPidFile()); UnregisterWallet(pwalletMain); delete pwalletMain; - CreateThread(ExitTimeout, NULL); + NewThread(ExitTimeout, NULL); Sleep(50); printf("Bitcoin exited\n\n"); fExit = true; @@ -225,7 +225,7 @@ std::string HelpMessage() " -datadir=<dir> " + _("Specify data directory") + "\n" + " -dbcache=<n> " + _("Set database cache size in megabytes (default: 25)") + "\n" + " -dblogsize=<n> " + _("Set database disk log size in megabytes (default: 100)") + "\n" + - " -timeout=<n> " + _("Specify connection timeout (in milliseconds)") + "\n" + + " -timeout=<n> " + _("Specify connection timeout in milliseconds (default: 5000))") + "\n" + " -proxy=<ip:port> " + _("Connect through socks proxy") + "\n" + " -socks=<n> " + _("Select the version of socks proxy to use (4-5, default: 5)") + "\n" + " -tor=<ip:port> " + _("Use proxy to reach tor hidden services (default: same as -proxy)") + "\n" @@ -761,11 +761,11 @@ bool AppInit2() printf("mapWallet.size() = %d\n", pwalletMain->mapWallet.size()); printf("mapAddressBook.size() = %d\n", pwalletMain->mapAddressBook.size()); - if (!CreateThread(StartNode, NULL)) + if (!NewThread(StartNode, NULL)) InitError(_("Error: could not start node")); if (fServer) - CreateThread(ThreadRPCServer, NULL); + NewThread(ThreadRPCServer, NULL); // ********************************************************* Step 11: finished diff --git a/src/main.cpp b/src/main.cpp index 71d425e15f..38d2b96f80 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2679,7 +2679,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) // In case we are on a very long side-chain, it is possible that we already have // the last block in an inv bundle sent in response to getblocks. Try to detect // this situation and push another getblocks to continue. - std::vector<CInv> vGetData(1,inv); pfrom->PushGetBlocks(mapBlockIndex[inv.hash], uint256(0)); if (fDebug) printf("force request: %s\n", inv.ToString().c_str()); @@ -4025,8 +4024,8 @@ void GenerateBitcoins(bool fGenerate, CWallet* pwallet) printf("Starting %d BitcoinMiner threads\n", nAddThreads); for (int i = 0; i < nAddThreads; i++) { - if (!CreateThread(ThreadBitcoinMiner, pwallet)) - printf("Error: CreateThread(ThreadBitcoinMiner) failed\n"); + if (!NewThread(ThreadBitcoinMiner, pwallet)) + printf("Error: NewThread(ThreadBitcoinMiner) failed\n"); Sleep(10); } } diff --git a/src/main.h b/src/main.h index dc9f9ee74a..b8057a295e 100644 --- a/src/main.h +++ b/src/main.h @@ -1174,7 +1174,7 @@ public: std::string ToString() const { - return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)", + return strprintf("CBlockIndex(pprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)", pprev, pnext, nFile, nBlockPos, nHeight, hashMerkleRoot.ToString().substr(0,10).c_str(), GetBlockHash().ToString().substr(0,20).c_str()); diff --git a/src/net.cpp b/src/net.cpp index dc55fae5c5..76e44a6cf8 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1020,9 +1020,7 @@ void ThreadMapPort2(void* parg) { printf("ThreadMapPort started\n"); - char port[6]; - sprintf(port, "%d", GetListenPort()); - + std::string port = strprintf("%d", GetListenPort()); const char * multicastif = 0; const char * minissdpdpath = 0; struct UPNPDev * devlist = 0; @@ -1065,23 +1063,23 @@ void ThreadMapPort2(void* parg) #ifndef UPNPDISCOVER_SUCCESS /* miniupnpc 1.5 */ r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, - port, port, lanaddr, strDesc.c_str(), "TCP", 0); + port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0); #else /* miniupnpc 1.6 */ r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, - port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0"); + port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0"); #endif if(r!=UPNPCOMMAND_SUCCESS) printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", - port, port, lanaddr, r, strupnperror(r)); + port.c_str(), port.c_str(), lanaddr, r, strupnperror(r)); else printf("UPnP Port Mapping successful.\n"); int i = 1; loop { if (fShutdown || !fUseUPnP) { - r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0); + r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0); printf("UPNP_DeletePortMapping() returned : %d\n", r); freeUPNPDevlist(devlist); devlist = 0; FreeUPNPUrls(&urls); @@ -1092,16 +1090,16 @@ void ThreadMapPort2(void* parg) #ifndef UPNPDISCOVER_SUCCESS /* miniupnpc 1.5 */ r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, - port, port, lanaddr, strDesc.c_str(), "TCP", 0); + port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0); #else /* miniupnpc 1.6 */ r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, - port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0"); + port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0"); #endif if(r!=UPNPCOMMAND_SUCCESS) printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", - port, port, lanaddr, r, strupnperror(r)); + port.c_str(), port.c_str(), lanaddr, r, strupnperror(r)); else printf("UPnP Port Mapping successful.\n");; } @@ -1125,7 +1123,7 @@ void MapPort() { if (fUseUPnP && vnThreadsRunning[THREAD_UPNP] < 1) { - if (!CreateThread(ThreadMapPort, NULL)) + if (!NewThread(ThreadMapPort, NULL)) printf("Error: ThreadMapPort(ThreadMapPort) failed\n"); } } @@ -1887,7 +1885,7 @@ void static Discover() // Don't use external IPv4 discovery, when -onlynet="IPv6" if (!IsLimited(NET_IPV4)) - CreateThread(ThreadGetMyExternalIP, NULL); + NewThread(ThreadGetMyExternalIP, NULL); } void StartNode(void* parg) @@ -1913,36 +1911,36 @@ void StartNode(void* parg) if (!GetBoolArg("-dnsseed", true)) printf("DNS seeding disabled\n"); else - if (!CreateThread(ThreadDNSAddressSeed, NULL)) - printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n"); + if (!NewThread(ThreadDNSAddressSeed, NULL)) + printf("Error: NewThread(ThreadDNSAddressSeed) failed\n"); // Map ports with UPnP if (fUseUPnP) MapPort(); // Get addresses from IRC and advertise ours - if (!CreateThread(ThreadIRCSeed, NULL)) - printf("Error: CreateThread(ThreadIRCSeed) failed\n"); + if (!NewThread(ThreadIRCSeed, NULL)) + printf("Error: NewThread(ThreadIRCSeed) failed\n"); // Send and receive from sockets, accept connections - if (!CreateThread(ThreadSocketHandler, NULL)) - printf("Error: CreateThread(ThreadSocketHandler) failed\n"); + if (!NewThread(ThreadSocketHandler, NULL)) + printf("Error: NewThread(ThreadSocketHandler) failed\n"); // Initiate outbound connections from -addnode - if (!CreateThread(ThreadOpenAddedConnections, NULL)) - printf("Error: CreateThread(ThreadOpenAddedConnections) failed\n"); + if (!NewThread(ThreadOpenAddedConnections, NULL)) + printf("Error: NewThread(ThreadOpenAddedConnections) failed\n"); // Initiate outbound connections - if (!CreateThread(ThreadOpenConnections, NULL)) - printf("Error: CreateThread(ThreadOpenConnections) failed\n"); + if (!NewThread(ThreadOpenConnections, NULL)) + printf("Error: NewThread(ThreadOpenConnections) failed\n"); // Process messages - if (!CreateThread(ThreadMessageHandler, NULL)) - printf("Error: CreateThread(ThreadMessageHandler) failed\n"); + if (!NewThread(ThreadMessageHandler, NULL)) + printf("Error: NewThread(ThreadMessageHandler) failed\n"); // Dump network addresses - if (!CreateThread(ThreadDumpAddress, NULL)) - printf("Error; CreateThread(ThreadDumpAddress) failed\n"); + if (!NewThread(ThreadDumpAddress, NULL)) + printf("Error; NewThread(ThreadDumpAddress) failed\n"); // Generate coins in the background GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain); diff --git a/src/qt/qtipcserver.cpp b/src/qt/qtipcserver.cpp index a2fe866e29..ec2d56b9e3 100644 --- a/src/qt/qtipcserver.cpp +++ b/src/qt/qtipcserver.cpp @@ -152,7 +152,7 @@ void ipcInit(int argc, char *argv[]) return; } - if (!CreateThread(ipcThread, mq)) + if (!NewThread(ipcThread, mq)) { delete mq; return; diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index d2cb31f51d..2954b9ee57 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -225,6 +225,10 @@ Value getblocktemplate(const Array& params, bool fHelp) const Value& modeval = find_value(oparam, "mode"); if (modeval.type() == str_type) strMode = modeval.get_str(); + else if (modeval.type() == null_type) + { + /* Do nothing */ + } else throw JSONRPCError(-8, "Invalid mode"); } diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index be83b85c15..929dde9c15 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -1006,7 +1006,8 @@ Value listtransactions(const Array& params, bool fHelp) Array ret; - CWallet::TxItems txOrdered = pwalletMain->OrderedTxItems(strAccount); + std::list<CAccountingEntry> acentries; + CWallet::TxItems txOrdered = pwalletMain->OrderedTxItems(acentries, strAccount); // iterate backwards until we have nCount items to return: for (CWallet::TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) @@ -1302,9 +1303,9 @@ Value walletpassphrase(const Array& params, bool fHelp) "walletpassphrase <passphrase> <timeout>\n" "Stores the wallet decryption key in memory for <timeout> seconds."); - CreateThread(ThreadTopUpKeyPool, NULL); + NewThread(ThreadTopUpKeyPool, NULL); int64* pnSleepTime = new int64(params[1].get_int64()); - CreateThread(ThreadCleanWalletPassphrase, pnSleepTime); + NewThread(ThreadCleanWalletPassphrase, pnSleepTime); return Value::null; } diff --git a/src/util.cpp b/src/util.cpp index 461f42d177..d1270348e0 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1299,3 +1299,15 @@ void RenameThread(const char* name) (void)name; #endif } + +bool NewThread(void(*pfn)(void*), void* parg) +{ + try + { + boost::thread(pfn, parg); // thread detaches when out of scope + } catch(boost::thread_resource_error &e) { + printf("Error creating thread: %s\n", e.what()); + return false; + } + return true; +} diff --git a/src/util.h b/src/util.h index 709b0e05bd..65923e68a3 100644 --- a/src/util.h +++ b/src/util.h @@ -539,65 +539,14 @@ public: } }; +bool NewThread(void(*pfn)(void*), void* parg); - - - - - - - - -// Note: It turns out we might have been able to use boost::thread -// by using TerminateThread(boost::thread.native_handle(), 0); #ifdef WIN32 -typedef HANDLE pthread_t; - -inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=false) -{ - DWORD nUnused = 0; - HANDLE hthread = - CreateThread( - NULL, // default security - 0, // inherit stack size from parent - (LPTHREAD_START_ROUTINE)pfn, // function pointer - parg, // argument - 0, // creation option, start immediately - &nUnused); // thread identifier - if (hthread == NULL) - { - printf("Error: CreateThread() returned %d\n", GetLastError()); - return (pthread_t)0; - } - if (!fWantHandle) - { - CloseHandle(hthread); - return (pthread_t)-1; - } - return hthread; -} - inline void SetThreadPriority(int nPriority) { SetThreadPriority(GetCurrentThread(), nPriority); } #else -inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=false) -{ - pthread_t hthread = 0; - int ret = pthread_create(&hthread, NULL, (void*(*)(void*))pfn, parg); - if (ret != 0) - { - printf("Error: pthread_create() returned %d\n", ret); - return (pthread_t)0; - } - if (!fWantHandle) - { - pthread_detach(hthread); - return (pthread_t)-1; - } - return hthread; -} #define THREAD_PRIORITY_LOWEST PRIO_MAX #define THREAD_PRIORITY_BELOW_NORMAL 2 diff --git a/src/wallet.cpp b/src/wallet.cpp index dc019d4924..2f312d809e 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -291,8 +291,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) return true; } -CWallet::TxItems -CWallet::OrderedTxItems(std::string strAccount) +CWallet::TxItems CWallet::OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount) { CWalletDB walletdb(strWalletFile); @@ -306,7 +305,7 @@ CWallet::OrderedTxItems(std::string strAccount) CWalletTx* wtx = &((*it).second); txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0))); } - list<CAccountingEntry> acentries; + acentries.clear(); walletdb.ListAccountCreditDebit(strAccount, acentries); BOOST_FOREACH(CAccountingEntry& entry, acentries) { @@ -375,7 +374,8 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn) { // Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future int64 latestTolerated = latestNow + 300; - TxItems txOrdered = OrderedTxItems(); + std::list<CAccountingEntry> acentries; + TxItems txOrdered = OrderedTxItems(acentries); for (TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) { CWalletTx *const pwtx = (*it).second.first; @@ -1385,7 +1385,7 @@ int CWallet::LoadWallet(bool& fFirstRunRet) return nLoadWalletRet; fFirstRunRet = !vchDefaultKey.IsValid(); - CreateThread(ThreadFlushWalletDB, &strWalletFile); + NewThread(ThreadFlushWalletDB, &strWalletFile); return DB_LOAD_OK; } diff --git a/src/wallet.h b/src/wallet.h index 44f8a17d37..7fd33629fe 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -146,7 +146,12 @@ public: typedef std::pair<CWalletTx*, CAccountingEntry*> TxPair; typedef std::multimap<int64, TxPair > TxItems; - TxItems OrderedTxItems(std::string strAccount = ""); + + /** Get the wallet's activity log + @return multimap of ordered transactions and accounting entries + @warning Returned pointers are *only* valid within the scope of passed acentries + */ + TxItems OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount = ""); void MarkDirty(); bool AddToWallet(const CWalletTx& wtxIn); |