Commit 469f43a8 authored by Francis Dupont's avatar Francis Dupont

[907-remove-kea-thread-library] Checkpoint (todo finish netconf)

parent 984c2b6c
......@@ -1784,8 +1784,6 @@ AC_CONFIG_FILES([Makefile
src/lib/util/python/gen_wiredata.py
src/lib/util/tests/Makefile
src/lib/util/tests/process_spawn_app.sh
src/lib/util/threads/Makefile
src/lib/util/threads/tests/Makefile
src/lib/util/unittests/Makefile
src/lib/yang/Makefile
src/lib/yang/pretests/Makefile
......
......@@ -74,7 +74,6 @@ ca_unittests_LDADD += $(top_builddir)/src/lib/dns/libkea-dns++.la
ca_unittests_LDADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la
ca_unittests_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la
ca_unittests_LDADD += $(top_builddir)/src/lib/log/libkea-log.la
ca_unittests_LDADD += $(top_builddir)/src/lib/util/threads/libkea-threads.la
ca_unittests_LDADD += $(top_builddir)/src/lib/testutils/libkea-testutils.la
ca_unittests_LDADD += $(top_builddir)/src/lib/util/libkea-util.la
ca_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
......
......@@ -16,13 +16,13 @@
#include <cc/command_interpreter.h>
#include <cc/data.h>
#include <process/testutils/d_test_stubs.h>
#include <util/threads/thread.h>
#include <boost/bind.hpp>
#include <boost/pointer_cast.hpp>
#include <gtest/gtest.h>
#include <testutils/sandbox.h>
#include <cstdlib>
#include <vector>
#include <thread>
using namespace isc::agent;
using namespace isc::asiolink;
......@@ -228,8 +228,7 @@ public:
// to this we need to run the server side socket at the same time as the
// client. Running IO service in a thread guarantees that the server
//responds as soon as it receives the control command.
isc::util::thread::Thread th(boost::bind(&IOService::run,
getIOService().get()));
std::thread th(boost::bind(&IOService::run, getIOService().get()));
// Wait for the IO service in thread to actually run.
......@@ -243,7 +242,7 @@ public:
getIOService()->stop();
// Wait for the thread to finish.
th.wait();
th.join();
// Cancel all asynchronous operations on the server.
server_socket_->stopServer();
......@@ -385,7 +384,7 @@ TEST_F(CtrlAgentCommandMgrTest, forwardListCommands) {
// to this we need to run the server side socket at the same time.
// Running IO service in a thread guarantees that the server responds
// as soon as it receives the control command.
isc::util::thread::Thread th(boost::bind(&IOService::run, getIOService().get()));
std::thread th(boost::bind(&IOService::run, getIOService().get()));
// Wait for the IO service in thread to actually run.
server_socket_->waitForRunning();
......@@ -398,7 +397,7 @@ TEST_F(CtrlAgentCommandMgrTest, forwardListCommands) {
getIOService()->stop();
// Wait for the thread to finish.
th.wait();
th.join();
// Cancel all asynchronous operations on the server.
server_socket_->stopServer();
......
......@@ -55,7 +55,6 @@ kea_netconf_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la
kea_netconf_LDADD += $(top_builddir)/src/lib/cc/libkea-cc.la
kea_netconf_LDADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
kea_netconf_LDADD += $(top_builddir)/src/lib/log/libkea-log.la
kea_netconf_LDADD += $(top_builddir)/src/lib/util/threads/libkea-threads.la
kea_netconf_LDADD += $(top_builddir)/src/lib/util/libkea-util.la
kea_netconf_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
kea_netconf_LDADD += $(LOG4CPLUS_LIBS) $(CRYPTO_LIBS) $(BOOST_LIBS) $(SYSREPO_LIBS)
......
// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
......@@ -14,15 +14,14 @@
#include <asiolink/io_error.h>
#include <cc/command_interpreter.h>
#include <config/timeouts.h>
#include <util/threads/thread.h>
#include <boost/pointer_cast.hpp>
#include <thread>
using namespace isc::asiolink;
using namespace isc::config;
using namespace isc::data;
using namespace isc::http;
using namespace isc::process;
using namespace isc::util::thread;
namespace isc {
namespace netconf {
......@@ -47,7 +46,7 @@ NetconfProcess::run() {
try {
// Initialize netconf agent in a thread.
Thread th([this]() {
std::thread th([this]() {
if (shouldShutdown()) {
return;
}
......@@ -67,7 +66,9 @@ NetconfProcess::run() {
// Call init.
agent_.init(cfg_mgr);
});
});
th.detach();
// Let's process incoming data or expiring timers in a loop until
// shutdown condition is detected.
......@@ -75,6 +76,7 @@ NetconfProcess::run() {
runIO();
}
stopIOService();
} catch (const std::exception& ex) {
LOG_FATAL(netconf_logger, NETCONF_FAILED).arg(ex.what());
try {
......
......@@ -66,7 +66,6 @@ netconf_unittests_LDADD += $(top_builddir)/src/lib/dns/libkea-dns++.la
netconf_unittests_LDADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la
netconf_unittests_LDADD += $(top_builddir)/src/lib/log/libkea-log.la
netconf_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
netconf_unittests_LDADD += $(top_builddir)/src/lib/util/threads/libkea-threads.la
netconf_unittests_LDADD += $(top_builddir)/src/lib/util/libkea-util.la
netconf_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
netconf_unittests_LDADD += $(LOG4CPLUS_LIBS) $(CRYPTO_LIBS)
......
......@@ -20,10 +20,9 @@
#include <http/tests/response_test.h>
#include <testutils/threaded_test.h>
#include <testutils/sandbox.h>
#include <util/threads/thread.h>
#include <util/threads/sync.h>
#include <gtest/gtest.h>
#include <sstream>
#include <thread>
using namespace std;
using namespace isc;
......@@ -33,12 +32,11 @@ using namespace isc::data;
using namespace isc::http;
using namespace isc::http::test;
using namespace isc::test;
using namespace isc::util::thread;
namespace {
/// @brief Type definition for the pointer to Thread objects.
typedef boost::shared_ptr<Thread> ThreadPtr;
typedef boost::shared_ptr<thread> ThreadPtr;
//////////////////////////////// STDOUT ////////////////////////////////
......@@ -149,7 +147,7 @@ public:
/// @brief Destructor.
virtual ~UnixControlSocketTest() {
if (thread_) {
thread_->wait();
thread_->join();
thread_.reset();
}
// io_service must be stopped after the thread returns,
......@@ -308,7 +306,7 @@ TEST_F(UnixControlSocketTest, configGet) {
ASSERT_TRUE(ucs);
// Run a reflecting server in a thread.
thread_.reset(new Thread([this]() { reflectServer(); }));
thread_.reset(new thread([this]() { reflectServer(); }));
waitReady();
......@@ -332,7 +330,7 @@ TEST_F(UnixControlSocketTest, configTest) {
ASSERT_TRUE(ucs);
// Run a reflecting server in a thread.
thread_.reset(new Thread([this]() { reflectServer(); }));
thread_.reset(new thread([this]() { reflectServer(); }));
waitReady();
......@@ -359,7 +357,7 @@ TEST_F(UnixControlSocketTest, configSet) {
ASSERT_TRUE(ucs);
// Run a reflecting server in a thread.
thread_.reset(new Thread([this]() { reflectServer(); }));
thread_.reset(new thread([this]() { reflectServer(); }));
waitReady();
......@@ -386,7 +384,7 @@ TEST_F(UnixControlSocketTest, timeout) {
ASSERT_TRUE(ucs);
// Run a timeout server in a thread.
thread_.reset(new Thread([this]() { waitReady(); }));
thread_.reset(new thread([this]() { waitReady(); }));
// Try configGet: it should get a communication error,
EXPECT_THROW(ucs->configGet("foo"), ControlSocketError);
......@@ -513,7 +511,7 @@ public:
/// @brief Destructor.
virtual ~HttpControlSocketTest() {
if (thread_) {
thread_->wait();
thread_->join();
thread_.reset();
}
// io_service must be stopped after the thread returns,
......@@ -546,7 +544,7 @@ public:
///
/// Run IO in a thread.
void start() {
thread_.reset(new Thread([this]() {
thread_.reset(new thread([this]() {
// The thread is ready to go. Signal it to the main
// thread so it can start the actual test.
signalReady();
......
......@@ -14,7 +14,6 @@
#include <asiolink/interval_timer.h>
#include <asiolink/io_service.h>
#include <cc/command_interpreter.h>
#include <util/threads/thread.h>
#include <yang/yang_models.h>
#include <yang/yang_revisions.h>
#include <yang/translator_config.h>
......@@ -24,6 +23,7 @@
#include <testutils/sandbox.h>
#include <gtest/gtest.h>
#include <sstream>
#include <thread>
using namespace std;
using namespace isc;
......@@ -35,7 +35,6 @@ using namespace isc::http;
using namespace isc::test;
using namespace isc::yang;
using namespace isc::yang::test;
using namespace isc::util::thread;
#ifndef HAVE_PRE_0_7_6_SYSREPO
using namespace sysrepo;
#endif
......@@ -46,7 +45,7 @@ namespace {
const string TEST_SOCKET = "test-socket";
/// @brief Type definition for the pointer to Thread objects.
typedef boost::shared_ptr<Thread> ThreadPtr;
typedef boost::shared_ptr<thread> ThreadPtr;
/// @brief Test version of the NetconfAgent class.
class NakedNetconfAgent : public NetconfAgent {
......@@ -107,7 +106,7 @@ public:
virtual ~NetconfAgentTest() {
NetconfProcess::shut_down = true;
if (thread_) {
thread_->wait();
thread_->join();
thread_.reset();
}
// io_service must be stopped after the thread returns,
......@@ -191,7 +190,7 @@ public:
io_service_->stop();
io_service_.reset();
if (thread_) {
thread_->wait();
thread_->join();
thread_.reset();
}
if (agent_) {
......@@ -460,7 +459,7 @@ TEST_F(NetconfAgentLogTest, logChanges) {
EXPECT_NO_THROW(subs->module_change_subscribe(KEA_DHCP4_SERVER.c_str(),
cb, 0, 0,
SR_SUBSCR_APPLY_ONLY));
thread_.reset(new Thread([this]() { io_service_->run(); }));
thread_.reset(new thread([this]() { io_service_->run(); }));
// Change configuration (subnet #1 moved from 10.0.0.0/24 to 10.0.1/0/24).
const YRTree tree1 = {
......@@ -527,7 +526,7 @@ TEST_F(NetconfAgentLogTest, logChanges2) {
EXPECT_NO_THROW(subs->module_change_subscribe(KEA_DHCP4_SERVER.c_str(),
cb, 0, 0,
SR_SUBSCR_APPLY_ONLY));
thread_.reset(new Thread([this]() { io_service_->run(); }));
thread_.reset(new thread([this]() { io_service_->run(); }));
// Change configuration (subnet #1 moved to #10).
string xpath = "/kea-dhcp4-server:config/subnet4[id='1']";
......@@ -625,7 +624,7 @@ TEST_F(NetconfAgentTest, keaConfig) {
CfgServersMapPair service_pair = *servers_map->begin();
// Launch server.
thread_.reset(new Thread([this]() { fakeServer(); signalStopped(); }));
thread_.reset(new thread([this]() { fakeServer(); signalStopped(); }));
// Wait until the server is listening.
waitReady();
......@@ -726,7 +725,7 @@ TEST_F(NetconfAgentTest, yangConfig) {
CfgServersMapPair service_pair = *servers_map->begin();
// Launch server.
thread_.reset(new Thread([this]() { fakeServer(); signalStopped();}));
thread_.reset(new thread([this]() { fakeServer(); signalStopped();}));
// Wait until the server is listening.
waitReady();
......@@ -893,7 +892,7 @@ TEST_F(NetconfAgentTest, update) {
EXPECT_EQ(2, agent_->subscriptions_.size());
// Launch server.
thread_.reset(new Thread([this]() { fakeServer(); signalStopped(); }));
thread_.reset(new thread([this]() { fakeServer(); signalStopped(); }));
// Wait until the server is listening.
waitReady();
......@@ -1023,7 +1022,7 @@ TEST_F(NetconfAgentTest, validate) {
EXPECT_EQ(2, agent_->subscriptions_.size());
// Launch server twice.
thread_.reset(new Thread([this]()
thread_.reset(new thread([this]()
{
fakeServer();
fakeServer();
......
......@@ -45,7 +45,6 @@ perfdhcp_LDADD += $(top_builddir)/src/lib/dns/libkea-dns++.la
perfdhcp_LDADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la
perfdhcp_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la
perfdhcp_LDADD += $(top_builddir)/src/lib/log/libkea-log.la
perfdhcp_LDADD += $(top_builddir)/src/lib/util/threads/libkea-threads.la
perfdhcp_LDADD += $(top_builddir)/src/lib/util/libkea-util.la
perfdhcp_LDADD += $(top_builddir)/src/lib/cc/libkea-cc.la
perfdhcp_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
......
......@@ -27,7 +27,7 @@ Receiver::start() {
run_flag_.clear();
isc_throw(isc::Unexpected, "run_flag_ should be false.");
}
recv_thread_.reset(new util::thread::Thread(boost::bind(&Receiver::run, this)));
recv_thread_.reset(new std::thread(boost::bind(&Receiver::run, this)));
}
void
......@@ -40,7 +40,7 @@ Receiver::stop() {
if (run_flag_.test_and_set()) {
// Clear flags to order the thread to stop its main loop.
run_flag_.clear();
recv_thread_->wait();
recv_thread_->join();
}
}
......@@ -59,7 +59,7 @@ Receiver::getPkt() {
return readPktFromSocket();
} else {
// In multi thread mode read packet from the queue which is feed by Receiver thread.
util::thread::Mutex::Locker lock(pkt_queue_mutex_);
std::lock_guard<std::mutex> lock(pkt_queue_mutex_);
if (pkt_queue_.empty()) {
if (ip_version_ == 4) {
return Pkt4Ptr();
......@@ -133,7 +133,7 @@ Receiver::receivePackets() {
if (pkt->getType() == DHCPOFFER || pkt->getType() == DHCPACK ||
pkt->getType() == DHCPV6_ADVERTISE || pkt->getType() == DHCPV6_REPLY) {
// Otherwise push the packet to the queue, to main thread.
util::thread::Mutex::Locker lock(pkt_queue_mutex_);
std::lock_guard<std::mutex> lock(pkt_queue_mutex_);
pkt_queue_.push(pkt);
}
}
......
......@@ -11,11 +11,10 @@
#include <perfdhcp/command_options.h>
#include <dhcp/pkt.h>
#include <util/threads/thread.h>
#include <util/threads/sync.h>
#include <queue>
#include <thread>
#include <mutex>
#include <boost/atomic.hpp>
namespace isc {
......@@ -38,13 +37,13 @@ private:
boost::atomic_flag run_flag_;
/// \brief Thread for receiving packets.
std::unique_ptr<util::thread::Thread> recv_thread_;
std::unique_ptr<std::thread> recv_thread_;
/// \brief Queue for passing packets from receiver thread to main thread.
std::queue<dhcp::PktPtr> pkt_queue_;
/// \brief Mutex for controlling access to the queue.
util::thread::Mutex pkt_queue_mutex_;
std::mutex pkt_queue_mutex_;
BasePerfSocket &socket_;
......
......@@ -48,7 +48,6 @@ run_unittests_LDADD += $(top_builddir)/src/lib/dns/libkea-dns++.la
run_unittests_LDADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la
run_unittests_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la
run_unittests_LDADD += $(top_builddir)/src/lib/log/libkea-log.la
run_unittests_LDADD += $(top_builddir)/src/lib/util/threads/libkea-threads.la
run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
run_unittests_LDADD += $(top_builddir)/src/lib/util/libkea-util.la
run_unittests_LDADD += $(top_builddir)/src/lib/cc/libkea-cc.la
......
......@@ -54,7 +54,6 @@ ha_unittests_LDADD += $(top_builddir)/src/lib/dns/libkea-dns++.la
ha_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
ha_unittests_LDADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la
ha_unittests_LDADD += $(top_builddir)/src/lib/log/libkea-log.la
ha_unittests_LDADD += $(top_builddir)/src/lib/util/threads/libkea-threads.la
ha_unittests_LDADD += $(top_builddir)/src/lib/util/libkea-util.la
ha_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
ha_unittests_LDADD += $(LOG4CPLUS_LIBS)
......
......@@ -930,7 +930,7 @@ public:
// Stop the IO service. This should cause the thread to terminate.
io_service_->stop();
thread->wait();
thread->join();
io_service_->get_io_service().reset();
io_service_->poll();
}
......@@ -979,7 +979,7 @@ public:
// Stop the IO service. This should cause the thread to terminate.
io_service_->stop();
thread->wait();
thread->join();
io_service_->get_io_service().reset();
io_service_->poll();
}
......
// Copyright (C) 2017-2018 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2017-2019 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
......@@ -93,22 +93,22 @@ HATest::runIOService(long ms, std::function<bool()> stop_condition) {
timer.cancel();
}
boost::shared_ptr<util::thread::Thread>
boost::shared_ptr<std::thread>
HATest::runIOServiceInThread() {
io_service_->get_io_service().reset();
bool running = false;
util::thread::Mutex mutex;
util::thread::CondVar condvar;
std::mutex mutex;
std::condition_variable condvar;
io_service_->post(boost::bind(&HATest::signalServiceRunning, this, boost::ref(running),
boost::ref(mutex), boost::ref(condvar)));
boost::shared_ptr<util::thread::Thread>
th(new util::thread::Thread(boost::bind(&IOService::run, io_service_.get())));
boost::shared_ptr<std::thread>
th(new std::thread(boost::bind(&IOService::run, io_service_.get())));
util::thread::Mutex::Locker lock(mutex);
std::unique_lock<std::mutex> lock(mutex);
while (!running) {
condvar.wait(mutex);
condvar.wait(lock);
}
return (th);
......@@ -124,17 +124,17 @@ HATest::testSynchronousCommands(std::function<void()> commands) {
// Stop the IO service. This should cause the thread to terminate.
io_service_->stop();
thread->wait();
thread->join();
}
void
HATest::signalServiceRunning(bool& running, util::thread::Mutex& mutex,
util::thread::CondVar& condvar) {
HATest::signalServiceRunning(bool& running, std::mutex& mutex,
std::condition_variable& condvar) {
{
util::thread::Mutex::Locker lock(mutex);
std::lock_guard<std::mutex> lock(mutex);
running = true;
}
condvar.signal();
condvar.notify_one();
}
void
......
......@@ -15,14 +15,14 @@
#include <dhcp/pkt6.h>
#include <dhcpsrv/network_state.h>
#include <hooks/libinfo.h>
#include <util/threads/sync.h>
#include <util/threads/thread.h>
#include <boost/shared_ptr.hpp>
#include <gtest/gtest.h>
#include <cstdint>
#include <functional>
#include <string>
#include <vector>
#include <mutex>
#include <thread>
namespace isc {
namespace ha {
......@@ -115,8 +115,7 @@ public:
/// @brief Runs IO service in a thread.
///
/// @return Shared pointer to the thread.
boost::shared_ptr<util::thread::Thread>
runIOServiceInThread();
boost::shared_ptr<std::thread> runIOServiceInThread();
/// @brief Executes commands while running IO service in a thread.
///
......@@ -132,8 +131,8 @@ protected:
/// IO service starts running and executes this function.
/// @param mutex reference to the mutex used for synchronization.
/// @param condvar reference to condition variable used for synchronization.
void signalServiceRunning(bool& running, util::thread::Mutex& mutex,
util::thread::CondVar& condvar);
void signalServiceRunning(bool& running, std::mutex& mutex,
std::condition_variable& condvar);
public:
......
// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
......@@ -6,8 +6,6 @@
#include <testutils/threaded_test.h>
using namespace isc::util::thread;
namespace isc {
namespace test {
......@@ -19,10 +17,10 @@ ThreadedTest::ThreadedTest()
void
ThreadedTest::doSignal(bool& flag) {
{
Mutex::Locker lock(mutex_);
std::lock_guard<std::mutex> lock(mutex_);
flag = true;
}
condvar_.signal();
condvar_.notify_one();
}
void
......@@ -42,9 +40,9 @@ ThreadedTest::signalStopped() {
void
ThreadedTest::doWait(bool& flag) {
Mutex::Locker lock(mutex_);
std::unique_lock<std::mutex> lock(mutex_);
while (!flag) {
condvar_.wait(mutex_);
condvar_.wait(lock);
}
}
......@@ -65,7 +63,7 @@ ThreadedTest::waitStopped() {
bool
ThreadedTest::isStopping() {
Mutex::Locker lock(mutex_);
std::lock_guard<std::mutex> lock(mutex_);
return (stopping_);
}
......
// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
......@@ -7,10 +7,10 @@
#ifndef THREADED_TEST_H
#define THREADED_TEST_H
#include <util/threads/thread.h>
#include <util/threads/sync.h>
#include <boost/shared_ptr.hpp>
#include <gtest/gtest.h>
#include <thread>
#include <mutex>
namespace isc {
namespace test {
......@@ -62,13 +62,13 @@ protected:
bool isStopping();
/// @brief Pointer to server thread.
boost::shared_ptr<util::thread::Thread> thread_;
boost::shared_ptr<std::thread> thread_;
/// @brief Mutex used to synchronize threads.
util::thread::Mutex mutex_;
std::mutex mutex_;
/// Condtional variable for thread waits.
util::thread::CondVar condvar_;
std::condition_variable condvar_;
/// Flag indicating that the thread is ready.
bool ready_;
......
AUTOMAKE_OPTIONS = subdir-objects
SUBDIRS = . io unittests tests python threads
SUBDIRS = . io unittests tests python
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += $(BOOST_INCLUDES)
......@@ -96,8 +96,3 @@ libkea_util_random_includedir = $(pkgincludedir)/util/random
libkea_util_random_include_HEADERS = \
random/qid_gen.h \
random/random_number_generator.h
libkea_util_threads_includedir = $(pkgincludedir)/util/threads
libkea_util_threads_include_HEADERS = \
threads/sync.h \
threads/thread.h
SUBDIRS = . tests
AM_CXXFLAGS = $(KEA_CXXFLAGS)
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += $(BOOST_INCLUDES)
lib_LTLIBRARIES = libkea-threads.la
libkea_threads_la_SOURCES = sync.h sync.cc
libkea_threads_la_SOURCES += thread.h thread.cc
libkea_threads_la_LIBADD = $(top_builddir)/src/lib/util/libkea-util.la
libkea_threads_la_LIBADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
libkea_threads_la_LDFLAGS = -no-undefined -version-info 3:0:0
CLEANFILES = *.gcno *.gcda
// Copyright (C) 2012-2016 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <config.h>
#include <util/threads/sync.h>
#include <exceptions/exceptions.h>
#include <cstring>
#include <memory>
#include <cerrno>
#include <cassert>
#include <pthread.h>
using std::unique_ptr;
namespace isc {
namespace util {
namespace thread {
class Mutex::Impl {
public:
Impl()
#ifdef ENABLE_DEBUG
: locked_count(0)
#endif // ENABLE_DEBUG
{}
pthread_mutex_t mutex;
#ifdef ENABLE_DEBUG
size_t locked_count;
#endif // ENABLE_DEBUG
};
namespace {
struct Deinitializer {
Deinitializer(pthread_mutexattr_t& attributes):
attributes_(attributes)
{}
~Deinitializer() {
const int result = pthread_mutexattr_destroy(&attributes_);
// This should never happen. According to the man page,
// if there's error, it's our fault.
assert(result == 0);
}
pthread_mutexattr_t& attributes_;
};
}
Mutex::Mutex() :
impl_(NULL)
{
pthread_mutexattr_t attributes;
int result = pthread_mutexattr_init(&attributes);
switch (result) {
case 0: // All 0K
break;
case ENOMEM:
throw std::bad_alloc();
default:
isc_throw(isc::InvalidOperation, std::strerror(result));
}
Deinitializer deinitializer(attributes);
// If debug mode is enabled in compilation, use the slower
// error-checking mutexes that detect deadlocks. Otherwise, use fast
// mutexes which don't. See the pthread_mutexattr_settype() POSIX
// documentation which describes these type attributes.
#ifdef ENABLE_DEBUG
result = pthread_mutexattr_settype(&attributes, PTHREAD_MUTEX_ERRORCHECK);
#else
result = pthread_mutexattr_settype(&attributes, PTHREAD_MUTEX_NORMAL);
#endif // ENABLE_DEBUG
if (result != 0) {
isc_throw(isc::InvalidOperation, std::strerror(result));
}
unique_ptr<Impl> impl(new Impl);
result = pthread_mutex_init(&impl->mutex, &attributes);