Merge #13743: refactor: Replace boost::bind with std::bind

cb53b825c2 scripted-diff: Replace boost::bind with std::bind (Chun Kuan Lee)
2196c51821 refactor: Use boost::scoped_connection in signal/slot, also prefer range-based loop instead of std::transform (Chun Kuan Lee)

Pull request description:

  Replace boost::bind with std::bind

  - In `src/rpc/server.cpp`, replace `std::transform` with simple loop.
  - In `src/validation.cpp`, store the `boost::signals2::connection` object and use it to disconnect.
  - In `src/validationinterface.cpp`, use 2 map to store the `boost::signals2::scoped_connection` object.

Tree-SHA512: 6653cbe00036fecfc495340618efcba6d7be0227c752b37b81a27184433330f817e8de9257774e9b35828026cb55f11ee7f17d6c388aebe22c4a3df13b5092f0
This commit is contained in:
MarcoFalke 2018-12-29 14:13:54 +01:00
commit cbb91cd0ec
No known key found for this signature in database
GPG Key ID: D2EA4850E7528B25
17 changed files with 83 additions and 96 deletions

View File

@ -78,7 +78,7 @@ static void AssembleBlock(benchmark::State& state)
::pcoinsTip.reset(new CCoinsViewCache(pcoinsdbview.get())); ::pcoinsTip.reset(new CCoinsViewCache(pcoinsdbview.get()));
const CChainParams& chainparams = Params(); const CChainParams& chainparams = Params();
thread_group.create_thread(boost::bind(&CScheduler::serviceQueue, &scheduler)); thread_group.create_thread(std::bind(&CScheduler::serviceQueue, &scheduler));
GetMainSignals().RegisterBackgroundSignalScheduler(scheduler); GetMainSignals().RegisterBackgroundSignalScheduler(scheduler);
LoadGenesisBlock(chainparams); LoadGenesisBlock(chainparams);
CValidationState state; CValidationState state;

View File

@ -59,7 +59,6 @@
#include <boost/algorithm/string/classification.hpp> #include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/replace.hpp> #include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/split.hpp> #include <boost/algorithm/string/split.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp> #include <boost/thread.hpp>
#include <openssl/crypto.h> #include <openssl/crypto.h>
@ -1237,8 +1236,8 @@ bool AppInitMain(InitInterfaces& interfaces)
} }
// Start the lightweight task scheduler thread // Start the lightweight task scheduler thread
CScheduler::Function serviceLoop = boost::bind(&CScheduler::serviceQueue, &scheduler); CScheduler::Function serviceLoop = std::bind(&CScheduler::serviceQueue, &scheduler);
threadGroup.create_thread(boost::bind(&TraceThread<CScheduler::Function>, "scheduler", serviceLoop)); threadGroup.create_thread(std::bind(&TraceThread<CScheduler::Function>, "scheduler", serviceLoop));
GetMainSignals().RegisterBackgroundSignalScheduler(scheduler); GetMainSignals().RegisterBackgroundSignalScheduler(scheduler);
GetMainSignals().RegisterWithMempoolSignals(mempool); GetMainSignals().RegisterWithMempoolSignals(mempool);
@ -1646,7 +1645,7 @@ bool AppInitMain(InitInterfaces& interfaces)
vImportFiles.push_back(strFile); vImportFiles.push_back(strFile);
} }
threadGroup.create_thread(boost::bind(&ThreadImport, vImportFiles)); threadGroup.create_thread(std::bind(&ThreadImport, vImportFiles));
// Wait for genesis block to be processed // Wait for genesis block to be processed
{ {

View File

@ -58,7 +58,6 @@
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QWindow> #include <QWindow>
#include <boost/bind.hpp>
const std::string BitcoinGUI::DEFAULT_UIPLATFORM = const std::string BitcoinGUI::DEFAULT_UIPLATFORM =
#if defined(Q_OS_MAC) #if defined(Q_OS_MAC)
@ -1294,8 +1293,8 @@ static bool ThreadSafeMessageBox(BitcoinGUI* gui, const std::string& message, co
void BitcoinGUI::subscribeToCoreSignals() void BitcoinGUI::subscribeToCoreSignals()
{ {
// Connect signals to client // Connect signals to client
m_handler_message_box = m_node.handleMessageBox(boost::bind(ThreadSafeMessageBox, this, _1, _2, _3)); m_handler_message_box = m_node.handleMessageBox(std::bind(ThreadSafeMessageBox, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
m_handler_question = m_node.handleQuestion(boost::bind(ThreadSafeMessageBox, this, _1, _3, _4)); m_handler_question = m_node.handleQuestion(std::bind(ThreadSafeMessageBox, this, std::placeholders::_1, std::placeholders::_3, std::placeholders::_4));
} }
void BitcoinGUI::unsubscribeFromCoreSignals() void BitcoinGUI::unsubscribeFromCoreSignals()

View File

@ -252,13 +252,13 @@ static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, int heig
void ClientModel::subscribeToCoreSignals() void ClientModel::subscribeToCoreSignals()
{ {
// Connect signals to client // Connect signals to client
m_handler_show_progress = m_node.handleShowProgress(boost::bind(ShowProgress, this, _1, _2)); m_handler_show_progress = m_node.handleShowProgress(std::bind(ShowProgress, this, std::placeholders::_1, std::placeholders::_2));
m_handler_notify_num_connections_changed = m_node.handleNotifyNumConnectionsChanged(boost::bind(NotifyNumConnectionsChanged, this, _1)); m_handler_notify_num_connections_changed = m_node.handleNotifyNumConnectionsChanged(std::bind(NotifyNumConnectionsChanged, this, std::placeholders::_1));
m_handler_notify_network_active_changed = m_node.handleNotifyNetworkActiveChanged(boost::bind(NotifyNetworkActiveChanged, this, _1)); m_handler_notify_network_active_changed = m_node.handleNotifyNetworkActiveChanged(std::bind(NotifyNetworkActiveChanged, this, std::placeholders::_1));
m_handler_notify_alert_changed = m_node.handleNotifyAlertChanged(boost::bind(NotifyAlertChanged, this)); m_handler_notify_alert_changed = m_node.handleNotifyAlertChanged(std::bind(NotifyAlertChanged, this));
m_handler_banned_list_changed = m_node.handleBannedListChanged(boost::bind(BannedListChanged, this)); m_handler_banned_list_changed = m_node.handleBannedListChanged(std::bind(BannedListChanged, this));
m_handler_notify_block_tip = m_node.handleNotifyBlockTip(boost::bind(BlockTipChanged, this, _1, _2, _3, _4, false)); m_handler_notify_block_tip = m_node.handleNotifyBlockTip(std::bind(BlockTipChanged, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, false));
m_handler_notify_header_tip = m_node.handleNotifyHeaderTip(boost::bind(BlockTipChanged, this, _1, _2, _3, _4, true)); m_handler_notify_header_tip = m_node.handleNotifyHeaderTip(std::bind(BlockTipChanged, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, true));
} }
void ClientModel::unsubscribeFromCoreSignals() void ClientModel::unsubscribeFromCoreSignals()

View File

@ -24,7 +24,6 @@
#include <QPainter> #include <QPainter>
#include <QRadialGradient> #include <QRadialGradient>
#include <boost/bind.hpp>
SplashScreen::SplashScreen(interfaces::Node& node, Qt::WindowFlags f, const NetworkStyle *networkStyle) : SplashScreen::SplashScreen(interfaces::Node& node, Qt::WindowFlags f, const NetworkStyle *networkStyle) :
QWidget(0, f), curAlignment(0), m_node(node) QWidget(0, f), curAlignment(0), m_node(node)
@ -174,7 +173,7 @@ static void ShowProgress(SplashScreen *splash, const std::string &title, int nPr
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
void SplashScreen::ConnectWallet(std::unique_ptr<interfaces::Wallet> wallet) void SplashScreen::ConnectWallet(std::unique_ptr<interfaces::Wallet> wallet)
{ {
m_connected_wallet_handlers.emplace_back(wallet->handleShowProgress(boost::bind(ShowProgress, this, _1, _2, false))); m_connected_wallet_handlers.emplace_back(wallet->handleShowProgress(std::bind(ShowProgress, this, std::placeholders::_1, std::placeholders::_2, false)));
m_connected_wallets.emplace_back(std::move(wallet)); m_connected_wallets.emplace_back(std::move(wallet));
} }
#endif #endif
@ -182,8 +181,8 @@ void SplashScreen::ConnectWallet(std::unique_ptr<interfaces::Wallet> wallet)
void SplashScreen::subscribeToCoreSignals() void SplashScreen::subscribeToCoreSignals()
{ {
// Connect signals to client // Connect signals to client
m_handler_init_message = m_node.handleInitMessage(boost::bind(InitMessage, this, _1)); m_handler_init_message = m_node.handleInitMessage(std::bind(InitMessage, this, std::placeholders::_1));
m_handler_show_progress = m_node.handleShowProgress(boost::bind(ShowProgress, this, _1, _2, _3)); m_handler_show_progress = m_node.handleShowProgress(std::bind(ShowProgress, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
m_handler_load_wallet = m_node.handleLoadWallet([this](std::unique_ptr<interfaces::Wallet> wallet) { ConnectWallet(std::move(wallet)); }); m_handler_load_wallet = m_node.handleLoadWallet([this](std::unique_ptr<interfaces::Wallet> wallet) { ConnectWallet(std::move(wallet)); });
#endif #endif

View File

@ -27,7 +27,6 @@
#include <QIcon> #include <QIcon>
#include <QList> #include <QList>
#include <boost/bind.hpp>
// Amount column is right-aligned it contains numbers // Amount column is right-aligned it contains numbers
static int column_alignments[] = { static int column_alignments[] = {
@ -745,8 +744,8 @@ static void ShowProgress(TransactionTableModel *ttm, const std::string &title, i
void TransactionTableModel::subscribeToCoreSignals() void TransactionTableModel::subscribeToCoreSignals()
{ {
// Connect signals to wallet // Connect signals to wallet
m_handler_transaction_changed = walletModel->wallet().handleTransactionChanged(boost::bind(NotifyTransactionChanged, this, _1, _2)); m_handler_transaction_changed = walletModel->wallet().handleTransactionChanged(std::bind(NotifyTransactionChanged, this, std::placeholders::_1, std::placeholders::_2));
m_handler_show_progress = walletModel->wallet().handleShowProgress(boost::bind(ShowProgress, this, _1, _2)); m_handler_show_progress = walletModel->wallet().handleShowProgress(std::bind(ShowProgress, this, std::placeholders::_1, std::placeholders::_2));
} }
void TransactionTableModel::unsubscribeFromCoreSignals() void TransactionTableModel::unsubscribeFromCoreSignals()

View File

@ -428,12 +428,12 @@ static void NotifyWatchonlyChanged(WalletModel *walletmodel, bool fHaveWatchonly
void WalletModel::subscribeToCoreSignals() void WalletModel::subscribeToCoreSignals()
{ {
// Connect signals to wallet // Connect signals to wallet
m_handler_unload = m_wallet->handleUnload(boost::bind(&NotifyUnload, this)); m_handler_unload = m_wallet->handleUnload(std::bind(&NotifyUnload, this));
m_handler_status_changed = m_wallet->handleStatusChanged(boost::bind(&NotifyKeyStoreStatusChanged, this)); m_handler_status_changed = m_wallet->handleStatusChanged(std::bind(&NotifyKeyStoreStatusChanged, this));
m_handler_address_book_changed = m_wallet->handleAddressBookChanged(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5)); m_handler_address_book_changed = m_wallet->handleAddressBookChanged(std::bind(NotifyAddressBookChanged, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
m_handler_transaction_changed = m_wallet->handleTransactionChanged(boost::bind(NotifyTransactionChanged, this, _1, _2)); m_handler_transaction_changed = m_wallet->handleTransactionChanged(std::bind(NotifyTransactionChanged, this, std::placeholders::_1, std::placeholders::_2));
m_handler_show_progress = m_wallet->handleShowProgress(boost::bind(ShowProgress, this, _1, _2)); m_handler_show_progress = m_wallet->handleShowProgress(std::bind(ShowProgress, this, std::placeholders::_1, std::placeholders::_2));
m_handler_watch_only_changed = m_wallet->handleWatchOnlyChanged(boost::bind(NotifyWatchonlyChanged, this, _1)); m_handler_watch_only_changed = m_wallet->handleWatchOnlyChanged(std::bind(NotifyWatchonlyChanged, this, std::placeholders::_1));
} }
void WalletModel::unsubscribeFromCoreSignals() void WalletModel::unsubscribeFromCoreSignals()

View File

@ -15,7 +15,6 @@
#include <util/strencodings.h> #include <util/strencodings.h>
#include <util/system.h> #include <util/system.h>
#include <boost/bind.hpp>
#include <boost/signals2/signal.hpp> #include <boost/signals2/signal.hpp>
#include <boost/algorithm/string/classification.hpp> #include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp> #include <boost/algorithm/string/split.hpp>
@ -504,11 +503,7 @@ UniValue CRPCTable::execute(const JSONRPCRequest &request) const
std::vector<std::string> CRPCTable::listCommands() const std::vector<std::string> CRPCTable::listCommands() const
{ {
std::vector<std::string> commandList; std::vector<std::string> commandList;
typedef std::map<std::string, const CRPCCommand*> commandMap; for (const auto& i : mapCommands) commandList.emplace_back(i.first);
std::transform( mapCommands.begin(), mapCommands.end(),
std::back_inserter(commandList),
boost::bind(&commandMap::value_type::first,_1) );
return commandList; return commandList;
} }

View File

@ -8,7 +8,6 @@
#include <reverselock.h> #include <reverselock.h>
#include <assert.h> #include <assert.h>
#include <boost/bind.hpp>
#include <utility> #include <utility>
CScheduler::CScheduler() : nThreadsServicingQueue(0), stopRequested(false), stopWhenEmpty(false) CScheduler::CScheduler() : nThreadsServicingQueue(0), stopRequested(false), stopWhenEmpty(false)
@ -120,12 +119,12 @@ void CScheduler::scheduleFromNow(CScheduler::Function f, int64_t deltaMilliSecon
static void Repeat(CScheduler* s, CScheduler::Function f, int64_t deltaMilliSeconds) static void Repeat(CScheduler* s, CScheduler::Function f, int64_t deltaMilliSeconds)
{ {
f(); f();
s->scheduleFromNow(boost::bind(&Repeat, s, f, deltaMilliSeconds), deltaMilliSeconds); s->scheduleFromNow(std::bind(&Repeat, s, f, deltaMilliSeconds), deltaMilliSeconds);
} }
void CScheduler::scheduleEvery(CScheduler::Function f, int64_t deltaMilliSeconds) void CScheduler::scheduleEvery(CScheduler::Function f, int64_t deltaMilliSeconds)
{ {
scheduleFromNow(boost::bind(&Repeat, this, f, deltaMilliSeconds), deltaMilliSeconds); scheduleFromNow(std::bind(&Repeat, this, f, deltaMilliSeconds), deltaMilliSeconds);
} }
size_t CScheduler::getQueueInfo(boost::chrono::system_clock::time_point &first, size_t CScheduler::getQueueInfo(boost::chrono::system_clock::time_point &first,

View File

@ -25,7 +25,7 @@
// CScheduler* s = new CScheduler(); // CScheduler* s = new CScheduler();
// s->scheduleFromNow(doSomething, 11); // Assuming a: void doSomething() { } // s->scheduleFromNow(doSomething, 11); // Assuming a: void doSomething() { }
// s->scheduleFromNow(std::bind(Class::func, this, argument), 3); // s->scheduleFromNow(std::bind(Class::func, this, argument), 3);
// boost::thread* t = new boost::thread(boost::bind(CScheduler::serviceQueue, s)); // boost::thread* t = new boost::thread(std::bind(CScheduler::serviceQueue, s));
// //
// ... then at program shutdown, clean up the thread running serviceQueue: // ... then at program shutdown, clean up the thread running serviceQueue:
// t->interrupt(); // t->interrupt();

View File

@ -7,7 +7,6 @@
#include <test/test_bitcoin.h> #include <test/test_bitcoin.h>
#include <boost/bind.hpp>
#include <boost/thread.hpp> #include <boost/thread.hpp>
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
@ -21,7 +20,7 @@ static void microTask(CScheduler& s, boost::mutex& mutex, int& counter, int delt
} }
boost::chrono::system_clock::time_point noTime = boost::chrono::system_clock::time_point::min(); boost::chrono::system_clock::time_point noTime = boost::chrono::system_clock::time_point::min();
if (rescheduleTime != noTime) { if (rescheduleTime != noTime) {
CScheduler::Function f = boost::bind(&microTask, boost::ref(s), boost::ref(mutex), boost::ref(counter), -delta + 1, noTime); CScheduler::Function f = std::bind(&microTask, std::ref(s), std::ref(mutex), std::ref(counter), -delta + 1, noTime);
s.schedule(f, rescheduleTime); s.schedule(f, rescheduleTime);
} }
} }
@ -69,8 +68,8 @@ BOOST_AUTO_TEST_CASE(manythreads)
boost::chrono::system_clock::time_point t = now + boost::chrono::microseconds(randomMsec(rng)); boost::chrono::system_clock::time_point t = now + boost::chrono::microseconds(randomMsec(rng));
boost::chrono::system_clock::time_point tReschedule = now + boost::chrono::microseconds(500 + randomMsec(rng)); boost::chrono::system_clock::time_point tReschedule = now + boost::chrono::microseconds(500 + randomMsec(rng));
int whichCounter = zeroToNine(rng); int whichCounter = zeroToNine(rng);
CScheduler::Function f = boost::bind(&microTask, boost::ref(microTasks), CScheduler::Function f = std::bind(&microTask, std::ref(microTasks),
boost::ref(counterMutex[whichCounter]), boost::ref(counter[whichCounter]), std::ref(counterMutex[whichCounter]), std::ref(counter[whichCounter]),
randomDelta(rng), tReschedule); randomDelta(rng), tReschedule);
microTasks.schedule(f, t); microTasks.schedule(f, t);
} }
@ -82,20 +81,20 @@ BOOST_AUTO_TEST_CASE(manythreads)
// As soon as these are created they will start running and servicing the queue // As soon as these are created they will start running and servicing the queue
boost::thread_group microThreads; boost::thread_group microThreads;
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
microThreads.create_thread(boost::bind(&CScheduler::serviceQueue, &microTasks)); microThreads.create_thread(std::bind(&CScheduler::serviceQueue, &microTasks));
MicroSleep(600); MicroSleep(600);
now = boost::chrono::system_clock::now(); now = boost::chrono::system_clock::now();
// More threads and more tasks: // More threads and more tasks:
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
microThreads.create_thread(boost::bind(&CScheduler::serviceQueue, &microTasks)); microThreads.create_thread(std::bind(&CScheduler::serviceQueue, &microTasks));
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
boost::chrono::system_clock::time_point t = now + boost::chrono::microseconds(randomMsec(rng)); boost::chrono::system_clock::time_point t = now + boost::chrono::microseconds(randomMsec(rng));
boost::chrono::system_clock::time_point tReschedule = now + boost::chrono::microseconds(500 + randomMsec(rng)); boost::chrono::system_clock::time_point tReschedule = now + boost::chrono::microseconds(500 + randomMsec(rng));
int whichCounter = zeroToNine(rng); int whichCounter = zeroToNine(rng);
CScheduler::Function f = boost::bind(&microTask, boost::ref(microTasks), CScheduler::Function f = std::bind(&microTask, std::ref(microTasks),
boost::ref(counterMutex[whichCounter]), boost::ref(counter[whichCounter]), std::ref(counterMutex[whichCounter]), std::ref(counter[whichCounter]),
randomDelta(rng), tReschedule); randomDelta(rng), tReschedule);
microTasks.schedule(f, t); microTasks.schedule(f, t);
} }
@ -126,7 +125,7 @@ BOOST_AUTO_TEST_CASE(singlethreadedscheduler_ordered)
// if they don't we'll get out of order behaviour // if they don't we'll get out of order behaviour
boost::thread_group threads; boost::thread_group threads;
for (int i = 0; i < 5; ++i) { for (int i = 0; i < 5; ++i) {
threads.create_thread(boost::bind(&CScheduler::serviceQueue, &scheduler)); threads.create_thread(std::bind(&CScheduler::serviceQueue, &scheduler));
} }
// these are not atomic, if SinglethreadedSchedulerClient prevents // these are not atomic, if SinglethreadedSchedulerClient prevents

View File

@ -89,7 +89,7 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha
// We have to run a scheduler thread to prevent ActivateBestChain // We have to run a scheduler thread to prevent ActivateBestChain
// from blocking due to queue overrun. // from blocking due to queue overrun.
threadGroup.create_thread(boost::bind(&CScheduler::serviceQueue, &scheduler)); threadGroup.create_thread(std::bind(&CScheduler::serviceQueue, &scheduler));
GetMainSignals().RegisterBackgroundSignalScheduler(scheduler); GetMainSignals().RegisterBackgroundSignalScheduler(scheduler);
mempool.setSanityCheck(1.0); mempool.setSanityCheck(1.0);

View File

@ -467,7 +467,7 @@ BOOST_AUTO_TEST_CASE(test_big_witness_transaction) {
CCheckQueueControl<CScriptCheck> control(&scriptcheckqueue); CCheckQueueControl<CScriptCheck> control(&scriptcheckqueue);
for (int i=0; i<20; i++) for (int i=0; i<20; i++)
threadGroup.create_thread(boost::bind(&CCheckQueue<CScriptCheck>::Thread, boost::ref(scriptcheckqueue))); threadGroup.create_thread(std::bind(&CCheckQueue<CScriptCheck>::Thread, std::ref(scriptcheckqueue)));
std::vector<Coin> coins; std::vector<Coin> coins;
for(uint32_t i = 0; i < mtx.vin.size(); i++) { for(uint32_t i = 0; i < mtx.vin.size(); i++) {

View File

@ -15,7 +15,6 @@
#include <set> #include <set>
#include <stdlib.h> #include <stdlib.h>
#include <boost/bind.hpp>
#include <boost/signals2/signal.hpp> #include <boost/signals2/signal.hpp>
#include <boost/algorithm/string/split.hpp> #include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp> #include <boost/algorithm/string/classification.hpp>
@ -459,8 +458,8 @@ TorController::TorController(struct event_base* _base, const std::string& _targe
if (!reconnect_ev) if (!reconnect_ev)
LogPrintf("tor: Failed to create event for reconnection: out of memory?\n"); LogPrintf("tor: Failed to create event for reconnection: out of memory?\n");
// Start connection attempts immediately // Start connection attempts immediately
if (!conn.Connect(_target, boost::bind(&TorController::connected_cb, this, _1), if (!conn.Connect(_target, std::bind(&TorController::connected_cb, this, std::placeholders::_1),
boost::bind(&TorController::disconnected_cb, this, _1) )) { std::bind(&TorController::disconnected_cb, this, std::placeholders::_1) )) {
LogPrintf("tor: Initiating connection to Tor control port %s failed\n", _target); LogPrintf("tor: Initiating connection to Tor control port %s failed\n", _target);
} }
// Read service private key if cached // Read service private key if cached
@ -538,7 +537,7 @@ void TorController::auth_cb(TorControlConnection& _conn, const TorControlReply&
// Note that the 'virtual' port doesn't have to be the same as our internal port, but this is just a convenient // Note that the 'virtual' port doesn't have to be the same as our internal port, but this is just a convenient
// choice. TODO; refactor the shutdown sequence some day. // choice. TODO; refactor the shutdown sequence some day.
_conn.Command(strprintf("ADD_ONION %s Port=%i,127.0.0.1:%i", private_key, GetListenPort(), GetListenPort()), _conn.Command(strprintf("ADD_ONION %s Port=%i,127.0.0.1:%i", private_key, GetListenPort(), GetListenPort()),
boost::bind(&TorController::add_onion_cb, this, _1, _2)); std::bind(&TorController::add_onion_cb, this, std::placeholders::_1, std::placeholders::_2));
} else { } else {
LogPrintf("tor: Authentication failed\n"); LogPrintf("tor: Authentication failed\n");
} }
@ -597,7 +596,7 @@ void TorController::authchallenge_cb(TorControlConnection& _conn, const TorContr
} }
std::vector<uint8_t> computedClientHash = ComputeResponse(TOR_SAFE_CLIENTKEY, cookie, clientNonce, serverNonce); std::vector<uint8_t> computedClientHash = ComputeResponse(TOR_SAFE_CLIENTKEY, cookie, clientNonce, serverNonce);
_conn.Command("AUTHENTICATE " + HexStr(computedClientHash), boost::bind(&TorController::auth_cb, this, _1, _2)); _conn.Command("AUTHENTICATE " + HexStr(computedClientHash), std::bind(&TorController::auth_cb, this, std::placeholders::_1, std::placeholders::_2));
} else { } else {
LogPrintf("tor: Invalid reply to AUTHCHALLENGE\n"); LogPrintf("tor: Invalid reply to AUTHCHALLENGE\n");
} }
@ -646,23 +645,23 @@ void TorController::protocolinfo_cb(TorControlConnection& _conn, const TorContro
if (methods.count("HASHEDPASSWORD")) { if (methods.count("HASHEDPASSWORD")) {
LogPrint(BCLog::TOR, "tor: Using HASHEDPASSWORD authentication\n"); LogPrint(BCLog::TOR, "tor: Using HASHEDPASSWORD authentication\n");
boost::replace_all(torpassword, "\"", "\\\""); boost::replace_all(torpassword, "\"", "\\\"");
_conn.Command("AUTHENTICATE \"" + torpassword + "\"", boost::bind(&TorController::auth_cb, this, _1, _2)); _conn.Command("AUTHENTICATE \"" + torpassword + "\"", std::bind(&TorController::auth_cb, this, std::placeholders::_1, std::placeholders::_2));
} else { } else {
LogPrintf("tor: Password provided with -torpassword, but HASHEDPASSWORD authentication is not available\n"); LogPrintf("tor: Password provided with -torpassword, but HASHEDPASSWORD authentication is not available\n");
} }
} else if (methods.count("NULL")) { } else if (methods.count("NULL")) {
LogPrint(BCLog::TOR, "tor: Using NULL authentication\n"); LogPrint(BCLog::TOR, "tor: Using NULL authentication\n");
_conn.Command("AUTHENTICATE", boost::bind(&TorController::auth_cb, this, _1, _2)); _conn.Command("AUTHENTICATE", std::bind(&TorController::auth_cb, this, std::placeholders::_1, std::placeholders::_2));
} else if (methods.count("SAFECOOKIE")) { } else if (methods.count("SAFECOOKIE")) {
// Cookie: hexdump -e '32/1 "%02x""\n"' ~/.tor/control_auth_cookie // Cookie: hexdump -e '32/1 "%02x""\n"' ~/.tor/control_auth_cookie
LogPrint(BCLog::TOR, "tor: Using SAFECOOKIE authentication, reading cookie authentication from %s\n", cookiefile); LogPrint(BCLog::TOR, "tor: Using SAFECOOKIE authentication, reading cookie authentication from %s\n", cookiefile);
std::pair<bool,std::string> status_cookie = ReadBinaryFile(cookiefile, TOR_COOKIE_SIZE); std::pair<bool,std::string> status_cookie = ReadBinaryFile(cookiefile, TOR_COOKIE_SIZE);
if (status_cookie.first && status_cookie.second.size() == TOR_COOKIE_SIZE) { if (status_cookie.first && status_cookie.second.size() == TOR_COOKIE_SIZE) {
// _conn.Command("AUTHENTICATE " + HexStr(status_cookie.second), boost::bind(&TorController::auth_cb, this, _1, _2)); // _conn.Command("AUTHENTICATE " + HexStr(status_cookie.second), std::bind(&TorController::auth_cb, this, std::placeholders::_1, std::placeholders::_2));
cookie = std::vector<uint8_t>(status_cookie.second.begin(), status_cookie.second.end()); cookie = std::vector<uint8_t>(status_cookie.second.begin(), status_cookie.second.end());
clientNonce = std::vector<uint8_t>(TOR_NONCE_SIZE, 0); clientNonce = std::vector<uint8_t>(TOR_NONCE_SIZE, 0);
GetRandBytes(clientNonce.data(), TOR_NONCE_SIZE); GetRandBytes(clientNonce.data(), TOR_NONCE_SIZE);
_conn.Command("AUTHCHALLENGE SAFECOOKIE " + HexStr(clientNonce), boost::bind(&TorController::authchallenge_cb, this, _1, _2)); _conn.Command("AUTHCHALLENGE SAFECOOKIE " + HexStr(clientNonce), std::bind(&TorController::authchallenge_cb, this, std::placeholders::_1, std::placeholders::_2));
} else { } else {
if (status_cookie.first) { if (status_cookie.first) {
LogPrintf("tor: Authentication cookie %s is not exactly %i bytes, as is required by the spec\n", cookiefile, TOR_COOKIE_SIZE); LogPrintf("tor: Authentication cookie %s is not exactly %i bytes, as is required by the spec\n", cookiefile, TOR_COOKIE_SIZE);
@ -684,7 +683,7 @@ void TorController::connected_cb(TorControlConnection& _conn)
{ {
reconnect_timeout = RECONNECT_TIMEOUT_START; reconnect_timeout = RECONNECT_TIMEOUT_START;
// First send a PROTOCOLINFO command to figure out what authentication is expected // First send a PROTOCOLINFO command to figure out what authentication is expected
if (!_conn.Command("PROTOCOLINFO 1", boost::bind(&TorController::protocolinfo_cb, this, _1, _2))) if (!_conn.Command("PROTOCOLINFO 1", std::bind(&TorController::protocolinfo_cb, this, std::placeholders::_1, std::placeholders::_2)))
LogPrintf("tor: Error sending initial protocolinfo command\n"); LogPrintf("tor: Error sending initial protocolinfo command\n");
} }
@ -711,8 +710,8 @@ void TorController::Reconnect()
/* Try to reconnect and reestablish if we get booted - for example, Tor /* Try to reconnect and reestablish if we get booted - for example, Tor
* may be restarting. * may be restarting.
*/ */
if (!conn.Connect(target, boost::bind(&TorController::connected_cb, this, _1), if (!conn.Connect(target, std::bind(&TorController::connected_cb, this, std::placeholders::_1),
boost::bind(&TorController::disconnected_cb, this, _1) )) { std::bind(&TorController::disconnected_cb, this, std::placeholders::_1) )) {
LogPrintf("tor: Re-initiating connection to Tor control port %s failed\n", target); LogPrintf("tor: Re-initiating connection to Tor control port %s failed\n", target);
} }
} }

View File

@ -2366,14 +2366,11 @@ class ConnectTrace {
private: private:
std::vector<PerBlockConnectTrace> blocksConnected; std::vector<PerBlockConnectTrace> blocksConnected;
CTxMemPool &pool; CTxMemPool &pool;
boost::signals2::scoped_connection m_connNotifyEntryRemoved;
public: public:
explicit ConnectTrace(CTxMemPool &_pool) : blocksConnected(1), pool(_pool) { explicit ConnectTrace(CTxMemPool &_pool) : blocksConnected(1), pool(_pool) {
pool.NotifyEntryRemoved.connect(boost::bind(&ConnectTrace::NotifyEntryRemoved, this, _1, _2)); m_connNotifyEntryRemoved = pool.NotifyEntryRemoved.connect(std::bind(&ConnectTrace::NotifyEntryRemoved, this, std::placeholders::_1, std::placeholders::_2));
}
~ConnectTrace() {
pool.NotifyEntryRemoved.disconnect(boost::bind(&ConnectTrace::NotifyEntryRemoved, this, _1, _2));
} }
void BlockConnected(CBlockIndex* pindex, std::shared_ptr<const CBlock> pblock) { void BlockConnected(CBlockIndex* pindex, std::shared_ptr<const CBlock> pblock) {

View File

@ -17,6 +17,18 @@
#include <boost/signals2/signal.hpp> #include <boost/signals2/signal.hpp>
struct ValidationInterfaceConnections {
boost::signals2::scoped_connection UpdatedBlockTip;
boost::signals2::scoped_connection TransactionAddedToMempool;
boost::signals2::scoped_connection BlockConnected;
boost::signals2::scoped_connection BlockDisconnected;
boost::signals2::scoped_connection TransactionRemovedFromMempool;
boost::signals2::scoped_connection ChainStateFlushed;
boost::signals2::scoped_connection Broadcast;
boost::signals2::scoped_connection BlockChecked;
boost::signals2::scoped_connection NewPoWValidBlock;
};
struct MainSignalsInstance { struct MainSignalsInstance {
boost::signals2::signal<void (const CBlockIndex *, const CBlockIndex *, bool fInitialDownload)> UpdatedBlockTip; boost::signals2::signal<void (const CBlockIndex *, const CBlockIndex *, bool fInitialDownload)> UpdatedBlockTip;
boost::signals2::signal<void (const CTransactionRef &)> TransactionAddedToMempool; boost::signals2::signal<void (const CTransactionRef &)> TransactionAddedToMempool;
@ -32,12 +44,18 @@ struct MainSignalsInstance {
// but must ensure all callbacks happen in-order, so we end up creating // but must ensure all callbacks happen in-order, so we end up creating
// our own queue here :( // our own queue here :(
SingleThreadedSchedulerClient m_schedulerClient; SingleThreadedSchedulerClient m_schedulerClient;
std::unordered_map<CValidationInterface*, ValidationInterfaceConnections> m_connMainSignals;
explicit MainSignalsInstance(CScheduler *pscheduler) : m_schedulerClient(pscheduler) {} explicit MainSignalsInstance(CScheduler *pscheduler) : m_schedulerClient(pscheduler) {}
}; };
static CMainSignals g_signals; static CMainSignals g_signals;
// This map has to a separate global instead of a member of MainSignalsInstance,
// because RegisterWithMempoolSignals is currently called before RegisterBackgroundSignalScheduler,
// so MainSignalsInstance hasn't been created yet.
static std::unordered_map<CTxMemPool*, boost::signals2::scoped_connection> g_connNotifyEntryRemoved;
void CMainSignals::RegisterBackgroundSignalScheduler(CScheduler& scheduler) { void CMainSignals::RegisterBackgroundSignalScheduler(CScheduler& scheduler) {
assert(!m_internals); assert(!m_internals);
m_internals.reset(new MainSignalsInstance(&scheduler)); m_internals.reset(new MainSignalsInstance(&scheduler));
@ -59,11 +77,11 @@ size_t CMainSignals::CallbacksPending() {
} }
void CMainSignals::RegisterWithMempoolSignals(CTxMemPool& pool) { void CMainSignals::RegisterWithMempoolSignals(CTxMemPool& pool) {
pool.NotifyEntryRemoved.connect(boost::bind(&CMainSignals::MempoolEntryRemoved, this, _1, _2)); g_connNotifyEntryRemoved.emplace(&pool, pool.NotifyEntryRemoved.connect(std::bind(&CMainSignals::MempoolEntryRemoved, this, std::placeholders::_1, std::placeholders::_2)));
} }
void CMainSignals::UnregisterWithMempoolSignals(CTxMemPool& pool) { void CMainSignals::UnregisterWithMempoolSignals(CTxMemPool& pool) {
pool.NotifyEntryRemoved.disconnect(boost::bind(&CMainSignals::MempoolEntryRemoved, this, _1, _2)); g_connNotifyEntryRemoved.erase(&pool);
} }
CMainSignals& GetMainSignals() CMainSignals& GetMainSignals()
@ -72,42 +90,27 @@ CMainSignals& GetMainSignals()
} }
void RegisterValidationInterface(CValidationInterface* pwalletIn) { void RegisterValidationInterface(CValidationInterface* pwalletIn) {
g_signals.m_internals->UpdatedBlockTip.connect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1, _2, _3)); ValidationInterfaceConnections& conns = g_signals.m_internals->m_connMainSignals[pwalletIn];
g_signals.m_internals->TransactionAddedToMempool.connect(boost::bind(&CValidationInterface::TransactionAddedToMempool, pwalletIn, _1)); conns.UpdatedBlockTip = g_signals.m_internals->UpdatedBlockTip.connect(std::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
g_signals.m_internals->BlockConnected.connect(boost::bind(&CValidationInterface::BlockConnected, pwalletIn, _1, _2, _3)); conns.TransactionAddedToMempool = g_signals.m_internals->TransactionAddedToMempool.connect(std::bind(&CValidationInterface::TransactionAddedToMempool, pwalletIn, std::placeholders::_1));
g_signals.m_internals->BlockDisconnected.connect(boost::bind(&CValidationInterface::BlockDisconnected, pwalletIn, _1)); conns.BlockConnected = g_signals.m_internals->BlockConnected.connect(std::bind(&CValidationInterface::BlockConnected, pwalletIn, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
g_signals.m_internals->TransactionRemovedFromMempool.connect(boost::bind(&CValidationInterface::TransactionRemovedFromMempool, pwalletIn, _1)); conns.BlockDisconnected = g_signals.m_internals->BlockDisconnected.connect(std::bind(&CValidationInterface::BlockDisconnected, pwalletIn, std::placeholders::_1));
g_signals.m_internals->ChainStateFlushed.connect(boost::bind(&CValidationInterface::ChainStateFlushed, pwalletIn, _1)); conns.TransactionRemovedFromMempool = g_signals.m_internals->TransactionRemovedFromMempool.connect(std::bind(&CValidationInterface::TransactionRemovedFromMempool, pwalletIn, std::placeholders::_1));
g_signals.m_internals->Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1, _2)); conns.ChainStateFlushed = g_signals.m_internals->ChainStateFlushed.connect(std::bind(&CValidationInterface::ChainStateFlushed, pwalletIn, std::placeholders::_1));
g_signals.m_internals->BlockChecked.connect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); conns.Broadcast = g_signals.m_internals->Broadcast.connect(std::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, std::placeholders::_1, std::placeholders::_2));
g_signals.m_internals->NewPoWValidBlock.connect(boost::bind(&CValidationInterface::NewPoWValidBlock, pwalletIn, _1, _2)); conns.BlockChecked = g_signals.m_internals->BlockChecked.connect(std::bind(&CValidationInterface::BlockChecked, pwalletIn, std::placeholders::_1, std::placeholders::_2));
conns.NewPoWValidBlock = g_signals.m_internals->NewPoWValidBlock.connect(std::bind(&CValidationInterface::NewPoWValidBlock, pwalletIn, std::placeholders::_1, std::placeholders::_2));
} }
void UnregisterValidationInterface(CValidationInterface* pwalletIn) { void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
g_signals.m_internals->BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); g_signals.m_internals->m_connMainSignals.erase(pwalletIn);
g_signals.m_internals->Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1, _2));
g_signals.m_internals->ChainStateFlushed.disconnect(boost::bind(&CValidationInterface::ChainStateFlushed, pwalletIn, _1));
g_signals.m_internals->TransactionAddedToMempool.disconnect(boost::bind(&CValidationInterface::TransactionAddedToMempool, pwalletIn, _1));
g_signals.m_internals->BlockConnected.disconnect(boost::bind(&CValidationInterface::BlockConnected, pwalletIn, _1, _2, _3));
g_signals.m_internals->BlockDisconnected.disconnect(boost::bind(&CValidationInterface::BlockDisconnected, pwalletIn, _1));
g_signals.m_internals->TransactionRemovedFromMempool.disconnect(boost::bind(&CValidationInterface::TransactionRemovedFromMempool, pwalletIn, _1));
g_signals.m_internals->UpdatedBlockTip.disconnect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1, _2, _3));
g_signals.m_internals->NewPoWValidBlock.disconnect(boost::bind(&CValidationInterface::NewPoWValidBlock, pwalletIn, _1, _2));
} }
void UnregisterAllValidationInterfaces() { void UnregisterAllValidationInterfaces() {
if (!g_signals.m_internals) { if (!g_signals.m_internals) {
return; return;
} }
g_signals.m_internals->BlockChecked.disconnect_all_slots(); g_signals.m_internals->m_connMainSignals.clear();
g_signals.m_internals->Broadcast.disconnect_all_slots();
g_signals.m_internals->ChainStateFlushed.disconnect_all_slots();
g_signals.m_internals->TransactionAddedToMempool.disconnect_all_slots();
g_signals.m_internals->BlockConnected.disconnect_all_slots();
g_signals.m_internals->BlockDisconnected.disconnect_all_slots();
g_signals.m_internals->TransactionRemovedFromMempool.disconnect_all_slots();
g_signals.m_internals->UpdatedBlockTip.disconnect_all_slots();
g_signals.m_internals->NewPoWValidBlock.disconnect_all_slots();
} }
void CallFunctionInValidationInterfaceQueue(std::function<void ()> func) { void CallFunctionInValidationInterfaceQueue(std::function<void ()> func) {

View File

@ -50,7 +50,6 @@ EXPECTED_BOOST_INCLUDES=(
boost/algorithm/string/classification.hpp boost/algorithm/string/classification.hpp
boost/algorithm/string/replace.hpp boost/algorithm/string/replace.hpp
boost/algorithm/string/split.hpp boost/algorithm/string/split.hpp
boost/bind.hpp
boost/chrono/chrono.hpp boost/chrono/chrono.hpp
boost/date_time/posix_time/posix_time.hpp boost/date_time/posix_time/posix_time.hpp
boost/filesystem.hpp boost/filesystem.hpp