Skip to content

Commit dc8be12

Browse files
committed
refactor: remove boost::thread_group usage
1 parent c8b8351 commit dc8be12

12 files changed

+44
-39
lines changed

Diff for: src/addrman.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include <logging.h>
1010
#include <serialize.h>
1111

12+
#include <cmath>
13+
1214
int CAddrInfo::GetTriedBucket(const uint256& nKey, const std::vector<bool> &asmap) const
1315
{
1416
uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << GetKey()).GetCheapHash();

Diff for: src/bitcoin-cli.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <util/url.h>
2222

2323
#include <algorithm>
24+
#include <cmath>
2425
#include <functional>
2526
#include <memory>
2627
#include <stdio.h>

Diff for: src/init.cpp

+4-7
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@
6868
#include <set>
6969
#include <stdint.h>
7070
#include <stdio.h>
71+
#include <thread>
72+
#include <vector>
7173

7274
#ifndef WIN32
7375
#include <attributes.h>
@@ -78,7 +80,6 @@
7880

7981
#include <boost/algorithm/string/replace.hpp>
8082
#include <boost/signals2/signal.hpp>
81-
#include <boost/thread/thread.hpp>
8283

8384
#if ENABLE_ZMQ
8485
#include <zmq/zmqabstractnotifier.h>
@@ -155,8 +156,6 @@ static std::unique_ptr<ECCVerifyHandle> globalVerifyHandle;
155156

156157
static std::thread g_load_block;
157158

158-
static boost::thread_group threadGroup;
159-
160159
void Interrupt(NodeContext& node)
161160
{
162161
InterruptHTTPServer();
@@ -218,11 +217,9 @@ void Shutdown(NodeContext& node)
218217
StopTorControl();
219218

220219
// After everything has been shut down, but before things get flushed, stop the
221-
// CScheduler/checkqueue, threadGroup and load block thread.
220+
// CScheduler/checkqueue, scheduler and load block thread.
222221
if (node.scheduler) node.scheduler->stop();
223222
if (g_load_block.joinable()) g_load_block.join();
224-
threadGroup.interrupt_all();
225-
threadGroup.join_all();
226223
StopScriptCheckWorkerThreads();
227224

228225
// After the threads that potentially access these pointers have been stopped,
@@ -1342,7 +1339,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA
13421339
node.scheduler = MakeUnique<CScheduler>();
13431340

13441341
// Start the lightweight task scheduler thread
1345-
threadGroup.create_thread([&] { TraceThread("scheduler", [&] { node.scheduler->serviceQueue(); }); });
1342+
node.scheduler->m_service_thread = std::thread([&] { TraceThread("scheduler", [&] { node.scheduler->serviceQueue(); }); });
13461343

13471344
// Gather some entropy once per minute.
13481345
node.scheduler->scheduleEvery([]{

Diff for: src/scheduler.h

+6-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <functional>
1010
#include <list>
1111
#include <map>
12+
#include <thread>
1213

1314
#include <sync.h>
1415

@@ -35,6 +36,8 @@ class CScheduler
3536
CScheduler();
3637
~CScheduler();
3738

39+
std::thread m_service_thread;
40+
3841
typedef std::function<void()> Function;
3942

4043
/** Call func at/after time t */
@@ -62,8 +65,7 @@ class CScheduler
6265
void MockForward(std::chrono::seconds delta_seconds);
6366

6467
/**
65-
* Services the queue 'forever'. Should be run in a thread,
66-
* and interrupted using boost::interrupt_thread
68+
* Services the queue 'forever'. Should be run in a thread.
6769
*/
6870
void serviceQueue();
6971

@@ -72,12 +74,14 @@ class CScheduler
7274
{
7375
WITH_LOCK(newTaskMutex, stopRequested = true);
7476
newTaskScheduled.notify_all();
77+
if (m_service_thread.joinable()) m_service_thread.join();
7578
}
7679
/** Tell any threads running serviceQueue to stop when there is no work left to be done */
7780
void StopWhenDrained()
7881
{
7982
WITH_LOCK(newTaskMutex, stopWhenEmpty = true);
8083
newTaskScheduled.notify_all();
84+
if (m_service_thread.joinable()) m_service_thread.join();
8185
}
8286

8387
/**

Diff for: src/script/sigcache.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#include <util/system.h>
1212

1313
#include <cuckoocache.h>
14+
15+
#include <boost/thread/lock_types.hpp>
1416
#include <boost/thread/shared_mutex.hpp>
1517

1618
namespace {

Diff for: src/test/checkqueue_tests.cpp

+10-7
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include <util/time.h>
1111

1212
#include <boost/test/unit_test.hpp>
13-
#include <boost/thread/thread.hpp>
1413

1514
#include <atomic>
1615
#include <condition_variable>
@@ -363,11 +362,11 @@ BOOST_AUTO_TEST_CASE(test_CheckQueueControl_Locks)
363362
{
364363
auto queue = MakeUnique<Standard_Queue>(QUEUE_BATCH_SIZE);
365364
{
366-
boost::thread_group tg;
365+
std::vector<std::thread> tg;
367366
std::atomic<int> nThreads {0};
368367
std::atomic<int> fails {0};
369368
for (size_t i = 0; i < 3; ++i) {
370-
tg.create_thread(
369+
tg.emplace_back(
371370
[&]{
372371
CCheckQueueControl<FakeCheck> control(queue.get());
373372
// While sleeping, no other thread should execute to this point
@@ -376,11 +375,13 @@ BOOST_AUTO_TEST_CASE(test_CheckQueueControl_Locks)
376375
fails += observed != nThreads;
377376
});
378377
}
379-
tg.join_all();
378+
for (auto& thread: tg) {
379+
if (thread.joinable()) thread.join();
380+
}
380381
BOOST_REQUIRE_EQUAL(fails, 0);
381382
}
382383
{
383-
boost::thread_group tg;
384+
std::vector<std::thread> tg;
384385
std::mutex m;
385386
std::condition_variable cv;
386387
bool has_lock{false};
@@ -389,7 +390,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueueControl_Locks)
389390
bool done_ack{false};
390391
{
391392
std::unique_lock<std::mutex> l(m);
392-
tg.create_thread([&]{
393+
tg.emplace_back([&]{
393394
CCheckQueueControl<FakeCheck> control(queue.get());
394395
std::unique_lock<std::mutex> ll(m);
395396
has_lock = true;
@@ -415,7 +416,9 @@ BOOST_AUTO_TEST_CASE(test_CheckQueueControl_Locks)
415416
cv.notify_one();
416417
BOOST_REQUIRE(!fails);
417418
}
418-
tg.join_all();
419+
for (auto& thread: tg) {
420+
if (thread.joinable()) thread.join();
421+
}
419422
}
420423
}
421424
BOOST_AUTO_TEST_SUITE_END()

Diff for: src/test/cuckoocache_tests.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// Distributed under the MIT software license, see the accompanying
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44
#include <boost/test/unit_test.hpp>
5+
#include <boost/thread/lock_types.hpp>
6+
#include <boost/thread/shared_mutex.hpp>
57
#include <cuckoocache.h>
68
#include <deque>
79
#include <random.h>

Diff for: src/test/scheduler_tests.cpp

+14-8
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@
77
#include <util/time.h>
88

99
#include <boost/test/unit_test.hpp>
10-
#include <boost/thread/thread.hpp>
1110

1211
#include <functional>
1312
#include <mutex>
13+
#include <thread>
14+
#include <vector>
1415

1516
BOOST_AUTO_TEST_SUITE(scheduler_tests)
1617

@@ -69,16 +70,16 @@ BOOST_AUTO_TEST_CASE(manythreads)
6970
BOOST_CHECK(last > now);
7071

7172
// As soon as these are created they will start running and servicing the queue
72-
boost::thread_group microThreads;
73+
std::vector<std::thread> microThreads;
7374
for (int i = 0; i < 5; i++)
74-
microThreads.create_thread(std::bind(&CScheduler::serviceQueue, &microTasks));
75+
microThreads.emplace_back(std::bind(&CScheduler::serviceQueue, &microTasks));
7576

7677
UninterruptibleSleep(std::chrono::microseconds{600});
7778
now = std::chrono::system_clock::now();
7879

7980
// More threads and more tasks:
8081
for (int i = 0; i < 5; i++)
81-
microThreads.create_thread(std::bind(&CScheduler::serviceQueue, &microTasks));
82+
microThreads.emplace_back(std::bind(&CScheduler::serviceQueue, &microTasks));
8283
for (int i = 0; i < 100; i++) {
8384
std::chrono::system_clock::time_point t = now + std::chrono::microseconds(randomMsec(rng));
8485
std::chrono::system_clock::time_point tReschedule = now + std::chrono::microseconds(500 + randomMsec(rng));
@@ -91,7 +92,10 @@ BOOST_AUTO_TEST_CASE(manythreads)
9192

9293
// Drain the task queue then exit threads
9394
microTasks.StopWhenDrained();
94-
microThreads.join_all(); // ... wait until all the threads are done
95+
// wait until all the threads are done
96+
for (auto& thread: microThreads) {
97+
if (thread.joinable()) thread.join();
98+
}
9599

96100
int counterSum = 0;
97101
for (int i = 0; i < 10; i++) {
@@ -131,9 +135,9 @@ BOOST_AUTO_TEST_CASE(singlethreadedscheduler_ordered)
131135
// if the queues only permit execution of one task at once then
132136
// the extra threads should effectively be doing nothing
133137
// if they don't we'll get out of order behaviour
134-
boost::thread_group threads;
138+
std::vector<std::thread> threads;
135139
for (int i = 0; i < 5; ++i) {
136-
threads.create_thread(std::bind(&CScheduler::serviceQueue, &scheduler));
140+
threads.emplace_back(std::bind(&CScheduler::serviceQueue, &scheduler));
137141
}
138142

139143
// these are not atomic, if SinglethreadedSchedulerClient prevents
@@ -157,7 +161,9 @@ BOOST_AUTO_TEST_CASE(singlethreadedscheduler_ordered)
157161

158162
// finish up
159163
scheduler.StopWhenDrained();
160-
threads.join_all();
164+
for (auto& thread: threads) {
165+
if (thread.joinable()) thread.join();
166+
}
161167

162168
BOOST_CHECK_EQUAL(counter1, 100);
163169
BOOST_CHECK_EQUAL(counter2, 100);

Diff for: src/test/util/setup_common.cpp

+1-3
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::ve
131131
// We have to run a scheduler thread to prevent ActivateBestChain
132132
// from blocking due to queue overrun.
133133
m_node.scheduler = MakeUnique<CScheduler>();
134-
threadGroup.create_thread([&] { TraceThread("scheduler", [&] { m_node.scheduler->serviceQueue(); }); });
134+
m_node.scheduler->m_service_thread = std::thread([&] { TraceThread("scheduler", [&] { m_node.scheduler->serviceQueue(); }); });
135135
GetMainSignals().RegisterBackgroundSignalScheduler(*m_node.scheduler);
136136

137137
pblocktree.reset(new CBlockTreeDB(1 << 20, true));
@@ -150,8 +150,6 @@ ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::ve
150150
ChainTestingSetup::~ChainTestingSetup()
151151
{
152152
if (m_node.scheduler) m_node.scheduler->stop();
153-
threadGroup.interrupt_all();
154-
threadGroup.join_all();
155153
StopScriptCheckWorkerThreads();
156154
GetMainSignals().FlushBackgroundCallbacks();
157155
GetMainSignals().UnregisterBackgroundSignalScheduler();

Diff for: src/test/util/setup_common.h

+1-3
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717
#include <util/string.h>
1818

1919
#include <type_traits>
20-
21-
#include <boost/thread/thread.hpp>
20+
#include <vector>
2221

2322
/** This is connected to the logger. Can be used to redirect logs to any other log */
2423
extern const std::function<void(const std::string&)> G_TEST_LOG_FUN;
@@ -88,7 +87,6 @@ struct BasicTestingSetup {
8887
* initialization behaviour.
8988
*/
9089
struct ChainTestingSetup : public BasicTestingSetup {
91-
boost::thread_group threadGroup;
9290

9391
explicit ChainTestingSetup(const std::string& chainName = CBaseChainParams::MAIN, const std::vector<const char*>& extra_args = {});
9492
~ChainTestingSetup();

Diff for: src/util/system.h

-7
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@
3535
#include <utility>
3636
#include <vector>
3737

38-
#include <boost/thread/condition_variable.hpp> // for boost::thread_interrupted
39-
4038
class UniValue;
4139

4240
// Application startup time (used for uptime calculation)
@@ -450,11 +448,6 @@ template <typename Callable> void TraceThread(const char* name, Callable func)
450448
func();
451449
LogPrintf("%s thread exit\n", name);
452450
}
453-
catch (const boost::thread_interrupted&)
454-
{
455-
LogPrintf("%s thread interrupt\n", name);
456-
throw;
457-
}
458451
catch (const std::exception& e) {
459452
PrintExceptionContinue(&e, name);
460453
throw;

Diff for: test/lint/lint-includes.sh

+1-2
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,8 @@ EXPECTED_BOOST_INCLUDES=(
6767
boost/signals2/optional_last_value.hpp
6868
boost/signals2/signal.hpp
6969
boost/test/unit_test.hpp
70-
boost/thread/condition_variable.hpp
70+
boost/thread/lock_types.hpp
7171
boost/thread/shared_mutex.hpp
72-
boost/thread/thread.hpp
7372
)
7473

7574
for BOOST_INCLUDE in $(git grep '^#include <boost/' -- "*.cpp" "*.h" | cut -f2 -d: | cut -f2 -d'<' | cut -f1 -d'>' | sort -u); do

0 commit comments

Comments
 (0)