core+main: switch to std::thread and thread_local
Change-Id: I892eb7d87639c2b0d24a8ed457b9d32635269216
diff --git a/core/global-io.cpp b/core/global-io.cpp
index f03d13c..e906999 100644
--- a/core/global-io.cpp
+++ b/core/global-io.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2018, Regents of the University of California,
+ * Copyright (c) 2014-2019, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -24,35 +24,35 @@
*/
#include "global-io.hpp"
-#include <boost/thread/tss.hpp>
namespace nfd {
-namespace scheduler {
-// defined in scheduler.cpp
-void
-resetGlobalScheduler();
-} // namespace scheduler
-
-static boost::thread_specific_ptr<boost::asio::io_service> g_ioService;
+static thread_local unique_ptr<boost::asio::io_service> g_ioService;
static boost::asio::io_service* g_mainIoService = nullptr;
static boost::asio::io_service* g_ribIoService = nullptr;
boost::asio::io_service&
getGlobalIoService()
{
- if (g_ioService.get() == nullptr) {
- g_ioService.reset(new boost::asio::io_service());
+ if (g_ioService == nullptr) {
+ g_ioService = make_unique<boost::asio::io_service>();
}
return *g_ioService;
}
+#ifdef WITH_TESTS
+namespace scheduler {
+void
+resetGlobalScheduler(); // defined in scheduler.cpp
+} // namespace scheduler
+
void
resetGlobalIoService()
{
scheduler::resetGlobalScheduler();
g_ioService.reset();
}
+#endif
void
setMainIoService(boost::asio::io_service* mainIo)
diff --git a/core/scheduler.cpp b/core/scheduler.cpp
index 094c188..68f7c75 100644
--- a/core/scheduler.cpp
+++ b/core/scheduler.cpp
@@ -26,20 +26,17 @@
#include "scheduler.hpp"
#include "global-io.hpp"
-#include <boost/thread/tss.hpp>
-
namespace nfd {
namespace scheduler {
-static boost::thread_specific_ptr<Scheduler> g_scheduler;
+static thread_local unique_ptr<Scheduler> g_scheduler;
Scheduler&
getGlobalScheduler()
{
- if (g_scheduler.get() == nullptr) {
- g_scheduler.reset(new Scheduler(getGlobalIoService()));
+ if (g_scheduler == nullptr) {
+ g_scheduler = make_unique<Scheduler>(getGlobalIoService());
}
-
return *g_scheduler;
}
@@ -49,11 +46,13 @@
return getGlobalScheduler().scheduleEvent(after, event);
}
+#ifdef WITH_TESTS
void
resetGlobalScheduler()
{
g_scheduler.reset();
}
+#endif
} // namespace scheduler
} // namespace nfd
diff --git a/daemon/main.cpp b/daemon/main.cpp
index f237a09..37f34b5 100644
--- a/daemon/main.cpp
+++ b/daemon/main.cpp
@@ -39,14 +39,12 @@
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>
-// boost::thread is used instead of std::thread to guarantee proper cleanup of thread local storage,
-// see https://www.boost.org/doc/libs/1_58_0/doc/html/thread/thread_local_storage.html
-#include <boost/thread.hpp>
#include <boost/version.hpp>
#include <atomic>
#include <condition_variable>
#include <iostream>
+#include <thread>
#include <ndn-cxx/util/logging.hpp>
#include <ndn-cxx/version.hpp>
@@ -118,33 +116,32 @@
std::mutex m;
std::condition_variable cv;
- std::string configFile = this->m_configFile; // c++11 lambda cannot capture member variables
- boost::thread ribThread([configFile, &retval, &ribIo, mainIo, &cv, &m] {
- {
- std::lock_guard<std::mutex> lock(m);
- ribIo = &getGlobalIoService();
- BOOST_ASSERT(ribIo != mainIo);
- setRibIoService(ribIo);
- }
- cv.notify_all(); // notify that ribIo has been assigned
+ std::thread ribThread([configFile = m_configFile, &retval, &ribIo, mainIo, &cv, &m] {
+ {
+ std::lock_guard<std::mutex> lock(m);
+ ribIo = &getGlobalIoService();
+ BOOST_ASSERT(ribIo != mainIo);
+ setRibIoService(ribIo);
+ }
+ cv.notify_all(); // notify that ribIo has been assigned
- try {
- ndn::KeyChain ribKeyChain;
- // must be created inside a separate thread
- rib::Service ribService(configFile, ribKeyChain);
- getGlobalIoService().run(); // ribIo is not thread-safe to use here
- }
- catch (const std::exception& e) {
- NFD_LOG_FATAL(boost::diagnostic_information(e));
- retval = 1;
- mainIo->stop();
- }
+ try {
+ ndn::KeyChain ribKeyChain;
+ // must be created inside a separate thread
+ rib::Service ribService(configFile, ribKeyChain);
+ getGlobalIoService().run(); // ribIo is not thread-safe to use here
+ }
+ catch (const std::exception& e) {
+ NFD_LOG_FATAL(boost::diagnostic_information(e));
+ retval = 1;
+ mainIo->stop();
+ }
- {
- std::lock_guard<std::mutex> lock(m);
- ribIo = nullptr;
- }
- });
+ {
+ std::lock_guard<std::mutex> lock(m);
+ ribIo = nullptr;
+ }
+ });
{
// Wait to guarantee that ribIo is properly initialized, so it can be used to terminate
diff --git a/tests/core/global-io.t.cpp b/tests/core/global-io.t.cpp
index 5aa3bc6..02f5c4c 100644
--- a/tests/core/global-io.t.cpp
+++ b/tests/core/global-io.t.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2018, Regents of the University of California,
+ * Copyright (c) 2014-2019, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -29,7 +29,7 @@
#include "tests/rib-io-fixture.hpp"
#include "tests/test-common.hpp"
-#include <boost/thread.hpp>
+#include <thread>
namespace nfd {
namespace tests {
@@ -40,9 +40,9 @@
{
boost::asio::io_service* s1 = &getGlobalIoService();
boost::asio::io_service* s2 = nullptr;
- boost::thread t([&s2] {
- s2 = &getGlobalIoService();
- });
+ std::thread t([&s2] {
+ s2 = &getGlobalIoService();
+ });
t.join();
@@ -60,10 +60,10 @@
BOOST_CHECK(&getGlobalIoService() == mainIo);
BOOST_CHECK(&getMainIoService() == mainIo);
BOOST_CHECK(&getRibIoService() == ribIo);
- auto mainThreadId = boost::this_thread::get_id();
+ auto mainThreadId = std::this_thread::get_id();
runOnRibIoService([&] {
- BOOST_CHECK(mainThreadId != boost::this_thread::get_id());
+ BOOST_CHECK(mainThreadId != std::this_thread::get_id());
BOOST_CHECK(&getGlobalIoService() == ribIo);
BOOST_CHECK(&getMainIoService() == mainIo);
BOOST_CHECK(&getRibIoService() == ribIo);
@@ -71,7 +71,7 @@
runOnRibIoService([&] {
runOnMainIoService([&] {
- BOOST_CHECK(mainThreadId == boost::this_thread::get_id());
+ BOOST_CHECK(mainThreadId == std::this_thread::get_id());
BOOST_CHECK(&getGlobalIoService() == mainIo);
BOOST_CHECK(&getMainIoService() == mainIo);
BOOST_CHECK(&getRibIoService() == ribIo);
@@ -83,7 +83,7 @@
{
bool hasRibRun = false;
runOnRibIoService([&] { hasRibRun = true; });
- boost::this_thread::sleep_for(1_s);
+ std::this_thread::sleep_for(std::chrono::seconds(1));
BOOST_CHECK_EQUAL(hasRibRun, false);
poll();
@@ -107,7 +107,7 @@
{
bool hasRibRun = false;
runOnRibIoService([&] { hasRibRun = true; });
- boost::this_thread::sleep_for(1_s);
+ std::this_thread::sleep_for(std::chrono::seconds(1));
BOOST_CHECK_EQUAL(hasRibRun, false);
advanceClocks(1_ns, 1);
diff --git a/tests/core/scheduler.t.cpp b/tests/core/scheduler.t.cpp
index 88adb03..8e319e0 100644
--- a/tests/core/scheduler.t.cpp
+++ b/tests/core/scheduler.t.cpp
@@ -27,7 +27,7 @@
#include "tests/test-common.hpp"
-#include <boost/thread.hpp>
+#include <thread>
namespace nfd {
namespace scheduler {
@@ -72,7 +72,7 @@
{
scheduler::Scheduler* s1 = &scheduler::getGlobalScheduler();
scheduler::Scheduler* s2 = nullptr;
- boost::thread t([&s2] { s2 = &scheduler::getGlobalScheduler(); });
+ std::thread t([&s2] { s2 = &scheduler::getGlobalScheduler(); });
t.join();
BOOST_CHECK(s1 != nullptr);
diff --git a/tests/rib-io-fixture.cpp b/tests/rib-io-fixture.cpp
index 91fc979..8702994 100644
--- a/tests/rib-io-fixture.cpp
+++ b/tests/rib-io-fixture.cpp
@@ -38,7 +38,7 @@
g_mainIo = &getGlobalIoService();
setMainIoService(g_mainIo);
- g_ribThread = boost::thread([&] {
+ g_ribThread = std::thread([&] {
{
std::lock_guard<std::mutex> lock(m);
g_ribIo = &getGlobalIoService();
diff --git a/tests/rib-io-fixture.hpp b/tests/rib-io-fixture.hpp
index fa43af5..f2bb892 100644
--- a/tests/rib-io-fixture.hpp
+++ b/tests/rib-io-fixture.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2018, Regents of the University of California,
+ * Copyright (c) 2014-2019, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -27,9 +27,10 @@
#define NFD_TESTS_RIB_IO_FIXTURE_HPP
#include "tests/test-common.hpp"
-#include <boost/thread.hpp>
+
#include <condition_variable>
#include <mutex>
+#include <thread>
namespace nfd {
namespace tests {
@@ -66,7 +67,7 @@
/** \brief global RIB thread
*/
- boost::thread g_ribThread;
+ std::thread g_ribThread;
private:
bool m_shouldStopRibIo = false;
diff --git a/wscript b/wscript
index 4722ece..6b7c556 100644
--- a/wscript
+++ b/wscript
@@ -109,7 +109,7 @@
conf.check_cxx(header_name='valgrind/valgrind.h', define_name='HAVE_VALGRIND', mandatory=False)
- boost_libs = ['system', 'program_options', 'filesystem', 'thread']
+ boost_libs = ['system', 'program_options', 'filesystem']
if conf.env.WITH_TESTS or conf.env.WITH_OTHER_TESTS:
boost_libs.append('unit_test_framework')