From 1adba86b37b9c11a8120e31cc4eeb137f8cde6d9 Mon Sep 17 00:00:00 2001 From: JINMEI Tatuya Date: Wed, 10 Oct 2012 16:00:28 -0700 Subject: [PATCH 01/19] [2332] unrelated cleanup: noncopyable doesn't have to be public inheritance (maybe a matter of taste, though) --- src/lib/util/threads/lock.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/util/threads/lock.h b/src/lib/util/threads/lock.h index fef537b9a5..f634bf8faa 100644 --- a/src/lib/util/threads/lock.h +++ b/src/lib/util/threads/lock.h @@ -41,7 +41,7 @@ namespace thread { /// /// The current interface is somewhat minimalistic. If we ever need more, we /// can add it later. -class Mutex : public boost::noncopyable { +class Mutex : boost::noncopyable { public: /// \brief Constructor. /// @@ -74,7 +74,7 @@ public: /// collecting" mechanism (auto_ptr, for example), it ensures exception /// safety with regards to the mutex - it'll get released on the exit /// of function no matter by what means. - class Locker : public boost::noncopyable { + class Locker : boost::noncopyable { public: /// \brief Constructor. /// From 8722bc208f5a232707824f3537fe0f6d073151f1 Mon Sep 17 00:00:00 2001 From: JINMEI Tatuya Date: Wed, 10 Oct 2012 16:24:21 -0700 Subject: [PATCH 02/19] [2332] added initial sets of condition variable encapsulation currently it does almost nothing except initialize and cleanup --- src/lib/util/threads/condvar.cc | 53 +++++++++++++++++++ src/lib/util/threads/condvar.h | 46 ++++++++++++++++ .../util/threads/tests/condvar_unittest.cc | 28 ++++++++++ 3 files changed, 127 insertions(+) create mode 100644 src/lib/util/threads/condvar.cc create mode 100644 src/lib/util/threads/condvar.h create mode 100644 src/lib/util/threads/tests/condvar_unittest.cc diff --git a/src/lib/util/threads/condvar.cc b/src/lib/util/threads/condvar.cc new file mode 100644 index 0000000000..6bdf38562d --- /dev/null +++ b/src/lib/util/threads/condvar.cc @@ -0,0 +1,53 @@ +// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "condvar.h" + +#include + +#include +#include + +namespace isc { +namespace util { +namespace thread { + +class CondVar::Impl { +public: + Impl() { + const int result = pthread_cond_init(&cond, NULL); + if (result != 0) { + isc_throw(isc::Unexpected, "pthread_cond_init failed: " + << std::strerror(result)); + } + } + ~Impl() { + const int result = pthread_cond_destroy(&cond); + assert(result == 0); + } + +private: + pthread_cond_t cond; +}; + +CondVar::CondVar() : impl_(new Impl) +{} + +CondVar::~CondVar() { + delete impl_; +} + +} // namespace thread +} // namespace util +} // namespace isc diff --git a/src/lib/util/threads/condvar.h b/src/lib/util/threads/condvar.h new file mode 100644 index 0000000000..2caf0aba79 --- /dev/null +++ b/src/lib/util/threads/condvar.h @@ -0,0 +1,46 @@ +// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#ifndef UTIL_THREADS_CONDVAR_H +#define UTIL_THREADS_CONDVAR_H 1 + +#include "lock.h" + +#include + +#include + +namespace isc { +namespace util { +namespace thread { + +// This class object internally holds pthread_cond_t and pthread_mutex_t +class CondVar : boost::noncopyable { +public: + CondVar(); + ~CondVar(); +private: + class Impl; + Impl* impl_; +}; + +} // namespace thread +} // namespace util +} // namespace isc + +#endif UTIL_THREADS_CONDVAR_H + +// Local Variables: +// mode: c++ +// End: diff --git a/src/lib/util/threads/tests/condvar_unittest.cc b/src/lib/util/threads/tests/condvar_unittest.cc new file mode 100644 index 0000000000..555a86a0e1 --- /dev/null +++ b/src/lib/util/threads/tests/condvar_unittest.cc @@ -0,0 +1,28 @@ +// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include +#include + +#include + +using namespace isc::util::thread; + +namespace { +TEST(CondVarTest, create) { + // Just construct and destruct it. Nothing unusual should happen. + EXPECT_NO_THROW(CondVar condvar); +} + +} From bc7551cca83bf060410a5645f014ddb0eb233834 Mon Sep 17 00:00:00 2001 From: JINMEI Tatuya Date: Wed, 10 Oct 2012 16:25:05 -0700 Subject: [PATCH 03/19] [2332] makefile updates for the new files --- src/lib/util/threads/Makefile.am | 1 + src/lib/util/threads/tests/Makefile.am | 1 + 2 files changed, 2 insertions(+) diff --git a/src/lib/util/threads/Makefile.am b/src/lib/util/threads/Makefile.am index 7b9fb8f859..9b3043ee4b 100644 --- a/src/lib/util/threads/Makefile.am +++ b/src/lib/util/threads/Makefile.am @@ -7,6 +7,7 @@ AM_CPPFLAGS += $(BOOST_INCLUDES) $(MULTITHREADING_FLAG) lib_LTLIBRARIES = libb10-threads.la libb10_threads_la_SOURCES = lock.h lock.cc libb10_threads_la_SOURCES += thread.h thread.cc +libb10_threads_la_SOURCES += condvar.h condvar.cc libb10_threads_la_LIBADD = $(top_builddir)/src/lib/exceptions/libb10-exceptions.la CLEANFILES = *.gcno *.gcda diff --git a/src/lib/util/threads/tests/Makefile.am b/src/lib/util/threads/tests/Makefile.am index 2d9d4f9b24..a12d221d18 100644 --- a/src/lib/util/threads/tests/Makefile.am +++ b/src/lib/util/threads/tests/Makefile.am @@ -23,6 +23,7 @@ TESTS += run_unittests run_unittests_SOURCES = run_unittests.cc run_unittests_SOURCES += thread_unittest.cc run_unittests_SOURCES += lock_unittest.cc +run_unittests_SOURCES += condvar_unittest.cc run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS) $(PTHREAD_LDFLAGS) From c0d50a204134b57f36a9e83cc694abcb5924f357 Mon Sep 17 00:00:00 2001 From: JINMEI Tatuya Date: Wed, 10 Oct 2012 16:45:41 -0700 Subject: [PATCH 04/19] [2332] removed unused changed --- src/lib/util/threads/Makefile.am | 1 - src/lib/util/threads/condvar.cc | 53 -------------------------------- src/lib/util/threads/condvar.h | 46 --------------------------- 3 files changed, 100 deletions(-) delete mode 100644 src/lib/util/threads/condvar.cc delete mode 100644 src/lib/util/threads/condvar.h diff --git a/src/lib/util/threads/Makefile.am b/src/lib/util/threads/Makefile.am index 9b3043ee4b..7b9fb8f859 100644 --- a/src/lib/util/threads/Makefile.am +++ b/src/lib/util/threads/Makefile.am @@ -7,7 +7,6 @@ AM_CPPFLAGS += $(BOOST_INCLUDES) $(MULTITHREADING_FLAG) lib_LTLIBRARIES = libb10-threads.la libb10_threads_la_SOURCES = lock.h lock.cc libb10_threads_la_SOURCES += thread.h thread.cc -libb10_threads_la_SOURCES += condvar.h condvar.cc libb10_threads_la_LIBADD = $(top_builddir)/src/lib/exceptions/libb10-exceptions.la CLEANFILES = *.gcno *.gcda diff --git a/src/lib/util/threads/condvar.cc b/src/lib/util/threads/condvar.cc deleted file mode 100644 index 6bdf38562d..0000000000 --- a/src/lib/util/threads/condvar.cc +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") -// -// Permission to use, copy, modify, and/or distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH -// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, -// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -// PERFORMANCE OF THIS SOFTWARE. - -#include "condvar.h" - -#include - -#include -#include - -namespace isc { -namespace util { -namespace thread { - -class CondVar::Impl { -public: - Impl() { - const int result = pthread_cond_init(&cond, NULL); - if (result != 0) { - isc_throw(isc::Unexpected, "pthread_cond_init failed: " - << std::strerror(result)); - } - } - ~Impl() { - const int result = pthread_cond_destroy(&cond); - assert(result == 0); - } - -private: - pthread_cond_t cond; -}; - -CondVar::CondVar() : impl_(new Impl) -{} - -CondVar::~CondVar() { - delete impl_; -} - -} // namespace thread -} // namespace util -} // namespace isc diff --git a/src/lib/util/threads/condvar.h b/src/lib/util/threads/condvar.h deleted file mode 100644 index 2caf0aba79..0000000000 --- a/src/lib/util/threads/condvar.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") -// -// Permission to use, copy, modify, and/or distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH -// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, -// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -// PERFORMANCE OF THIS SOFTWARE. - -#ifndef UTIL_THREADS_CONDVAR_H -#define UTIL_THREADS_CONDVAR_H 1 - -#include "lock.h" - -#include - -#include - -namespace isc { -namespace util { -namespace thread { - -// This class object internally holds pthread_cond_t and pthread_mutex_t -class CondVar : boost::noncopyable { -public: - CondVar(); - ~CondVar(); -private: - class Impl; - Impl* impl_; -}; - -} // namespace thread -} // namespace util -} // namespace isc - -#endif UTIL_THREADS_CONDVAR_H - -// Local Variables: -// mode: c++ -// End: From 43959b29a67ba17054bd4bb70b6fe3b8be3b2f2a Mon Sep 17 00:00:00 2001 From: JINMEI Tatuya Date: Wed, 10 Oct 2012 20:09:58 -0700 Subject: [PATCH 05/19] [2332] supported wait() and signal() --- src/lib/util/threads/lock.cc | 62 ++++++++++++++++++- src/lib/util/threads/lock.h | 31 +++++++++- .../util/threads/tests/condvar_unittest.cc | 49 ++++++++++++++- 3 files changed, 136 insertions(+), 6 deletions(-) diff --git a/src/lib/util/threads/lock.cc b/src/lib/util/threads/lock.cc index 6a165aa531..c33ec4202c 100644 --- a/src/lib/util/threads/lock.cc +++ b/src/lib/util/threads/lock.cc @@ -109,6 +109,14 @@ Mutex::~Mutex() { } } +void +Mutex::postLockAction() { + if (impl_->locked_count != 0) { + isc_throw(isc::InvalidOperation, "Lock attempt for locked mutex"); + } + ++impl_->locked_count; +} + void Mutex::lock() { assert(impl_ != NULL); @@ -116,13 +124,21 @@ Mutex::lock() { if (result != 0) { isc_throw(isc::InvalidOperation, std::strerror(result)); } - ++impl_->locked_count; // Only in debug mode + postLockAction(); // Only in debug mode +} + +void +Mutex::preUnlockAction() { + if (impl_->locked_count == 0) { + isc_throw(isc::InvalidOperation, "Unlock attempt for unlocked mutex"); + } + --impl_->locked_count; } void Mutex::unlock() { assert(impl_ != NULL); - --impl_->locked_count; // Only in debug mode + preUnlockAction(); // Only in debug mode const int result = pthread_mutex_unlock(&impl_->mutex); assert(result == 0); // This should never be possible } @@ -133,6 +149,48 @@ Mutex::locked() const { return (impl_->locked_count != 0); } +class CondVar::Impl { +public: + Impl() { + const int result = pthread_cond_init(&cond_, NULL); + if (result != 0) { + isc_throw(isc::Unexpected, "pthread_cond_init failed: " + << std::strerror(result)); + } + } + ~Impl() { + const int result = pthread_cond_destroy(&cond_); + assert(result == 0); + } + + // For convenience allow the main class to access this directly. + pthread_cond_t cond_; +}; + +CondVar::CondVar() : impl_(new Impl) +{} + +CondVar::~CondVar() { + delete impl_; +} + +void +CondVar::wait(Mutex& mutex) { + mutex.preUnlockAction(); // Only in debug mode + const int result = pthread_cond_wait(&impl_->cond_, &mutex.impl_->mutex); + mutex.postLockAction(); // Only in debug mode + assert(result == 0); +} + +void +CondVar::signal() { + const int result = pthread_cond_signal(&impl_->cond_); + + // pthread_cond_signal() can only fail when if cond_ is invalid. It + //should be impossible as long as this is a valid CondVar object. + assert(result == 0); +} + } } } diff --git a/src/lib/util/threads/lock.h b/src/lib/util/threads/lock.h index f634bf8faa..baa3fa4665 100644 --- a/src/lib/util/threads/lock.h +++ b/src/lib/util/threads/lock.h @@ -22,6 +22,7 @@ namespace isc { namespace util { namespace thread { +class CondVar; /// \brief Mutex with very simple interface /// @@ -114,15 +115,39 @@ public: /// \todo Disable in non-debug build bool locked() const; private: + friend class CondVar; + + // Commonly called after acquiring the lock, checking and updating + // internal state for debug. + void postLockAction(); + + // Commonly called before releasing the lock, checking and updating + // internal state for debug. + void preUnlockAction(); + class Impl; Impl* impl_; void lock(); void unlock(); }; +class CondVar : boost::noncopyable { +public: + CondVar(); + ~CondVar(); + void wait(Mutex& mutex); + void signal(); +private: + class Impl; + Impl* impl_; +}; -} -} -} +} // namespace thread +} // namespace util +} // namespace isc #endif + +// Local Variables: +// mode: c++ +// End: diff --git a/src/lib/util/threads/tests/condvar_unittest.cc b/src/lib/util/threads/tests/condvar_unittest.cc index 555a86a0e1..5a533c2c09 100644 --- a/src/lib/util/threads/tests/condvar_unittest.cc +++ b/src/lib/util/threads/tests/condvar_unittest.cc @@ -13,10 +13,17 @@ // PERFORMANCE OF THIS SOFTWARE. #include -#include +#include #include +#include + +#include + +#include +#include + using namespace isc::util::thread; namespace { @@ -25,4 +32,44 @@ TEST(CondVarTest, create) { EXPECT_NO_THROW(CondVar condvar); } +// Running on a separate thread, just updating the argument and waking up +// the other thread via the condition variable passed. +void +ringSignal(CondVar* condvar, Mutex* mutex, bool* arg) { + assert(*arg == false); + Mutex::Locker locker(*mutex); + *arg = true; + condvar->signal(); +} + +void +no_handler(int) {} + +// A simple wait-signal operation on a condition variable. +TEST(CondVarTest, waitAndSignal) { + CondVar condvar; + Mutex mutex; + + struct sigaction ignored, original; + std::memset(&ignored, 0, sizeof(ignored)); + ignored.sa_handler = no_handler; + if (sigaction(SIGALRM, &ignored, &original) != 0) { + FAIL() << "Couldn't set alarm"; + } + alarm(10); // 10sec duration: arbitrary choice + + Mutex::Locker locker(mutex); + bool must_become_true = false; // let the other thread reset it to true + Thread t(boost::bind(&ringSignal, &condvar, &mutex, &must_become_true)); + condvar.wait(mutex); + t.wait(); + EXPECT_TRUE(must_become_true); + + // Cancel the alarm and return the original handler + alarm(0); + if (sigaction(SIGALRM, &original, NULL)) { + FAIL() << "Couldn't restore alarm"; + } +} + } From 28b3efcf6100d2eab66c407a8f7ec54a87ac5f87 Mon Sep 17 00:00:00 2001 From: JINMEI Tatuya Date: Wed, 10 Oct 2012 22:17:25 -0700 Subject: [PATCH 06/19] [2332] added more tests and some more comments --- src/lib/util/threads/lock.cc | 13 +- .../util/threads/tests/condvar_unittest.cc | 150 ++++++++++++++---- 2 files changed, 134 insertions(+), 29 deletions(-) diff --git a/src/lib/util/threads/lock.cc b/src/lib/util/threads/lock.cc index c33ec4202c..13d0a0d671 100644 --- a/src/lib/util/threads/lock.cc +++ b/src/lib/util/threads/lock.cc @@ -160,6 +160,11 @@ public: } ~Impl() { const int result = pthread_cond_destroy(&cond_); + + // This can happen if we try to destroy cond_ while some other thread + // is waiting on it. assert() may be too strong for such a case, + // but we cannot safely destroy cond_ anyway. In order to avoid + // throwing from a destructor we simply let the process die. assert(result == 0); } @@ -179,7 +184,13 @@ CondVar::wait(Mutex& mutex) { mutex.preUnlockAction(); // Only in debug mode const int result = pthread_cond_wait(&impl_->cond_, &mutex.impl_->mutex); mutex.postLockAction(); // Only in debug mode - assert(result == 0); + + // pthread_cond_wait should normally succeed unless mutex is completely + // broken. + if (result != 0) { + isc_throw(isc::BadValue, "pthread_cond_wait failed unexpectedly: " << + std::strerror(result)); + } } void diff --git a/src/lib/util/threads/tests/condvar_unittest.cc b/src/lib/util/threads/tests/condvar_unittest.cc index 5a533c2c09..2695f842a3 100644 --- a/src/lib/util/threads/tests/condvar_unittest.cc +++ b/src/lib/util/threads/tests/condvar_unittest.cc @@ -12,12 +12,15 @@ // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. +#include + #include #include #include #include +#include #include @@ -27,7 +30,42 @@ using namespace isc::util::thread; namespace { -TEST(CondVarTest, create) { +// Used as a signal handler below. +volatile bool do_exit; // use for emergency escape +void +alarmHandler(int) { + do_exit = true; +} + +class CondVarTest : public ::testing::Test { +protected: + // We use a signal in case some of the thread synchronization tests + // unexpectedly cause a deadlock. + void SetUp() { + do_exit = false; + + std::memset(&handler_, 0, sizeof(handler_)); + handler_.sa_handler = alarmHandler; + if (sigaction(SIGALRM, &handler_, &original_) != 0) { + FAIL() << "Couldn't set alarm"; + } + alarm(10); // 10sec duration: arbitrary choice + } + void TearDown() { + // Cancel the alarm and return the original handler + alarm(0); + if (sigaction(SIGALRM, &original_, NULL)) { + FAIL() << "Couldn't restore alarm"; + } + } + + CondVar condvar_; + Mutex mutex_; +private: + struct sigaction handler_, original_; +}; + +TEST(CondVarTest0, create) { // Just construct and destruct it. Nothing unusual should happen. EXPECT_NO_THROW(CondVar condvar); } @@ -35,41 +73,97 @@ TEST(CondVarTest, create) { // Running on a separate thread, just updating the argument and waking up // the other thread via the condition variable passed. void -ringSignal(CondVar* condvar, Mutex* mutex, bool* arg) { - assert(*arg == false); +ringSignal(CondVar* condvar, Mutex* mutex, int* arg) { + assert(*arg == 0); Mutex::Locker locker(*mutex); - *arg = true; + ++*arg; condvar->signal(); } -void -no_handler(int) {} - // A simple wait-signal operation on a condition variable. -TEST(CondVarTest, waitAndSignal) { - CondVar condvar; - Mutex mutex; - - struct sigaction ignored, original; - std::memset(&ignored, 0, sizeof(ignored)); - ignored.sa_handler = no_handler; - if (sigaction(SIGALRM, &ignored, &original) != 0) { - FAIL() << "Couldn't set alarm"; - } - alarm(10); // 10sec duration: arbitrary choice - - Mutex::Locker locker(mutex); - bool must_become_true = false; // let the other thread reset it to true - Thread t(boost::bind(&ringSignal, &condvar, &mutex, &must_become_true)); - condvar.wait(mutex); +TEST_F(CondVarTest, waitAndSignal) { + Mutex::Locker locker(mutex_); + int shared_var = 0; // let the other thread increment this + Thread t(boost::bind(&ringSignal, &condvar_, &mutex_, &shared_var)); + condvar_.wait(mutex_); t.wait(); - EXPECT_TRUE(must_become_true); + EXPECT_EQ(1, shared_var); +} - // Cancel the alarm and return the original handler - alarm(0); - if (sigaction(SIGALRM, &original, NULL)) { - FAIL() << "Couldn't restore alarm"; +// Thread's main code for the next test +void +signalAndWait(CondVar* condvar1, CondVar* condvar2, Mutex* mutex, int* arg) { + Mutex::Locker locker(*mutex); + ++*arg; + condvar2->signal(); // let the main thread know this one is ready + condvar1->wait(*mutex); + ++*arg; +} + +// Similar to the previous test, but having two threads wait for a condvar. +TEST_F(CondVarTest, multiWaits) { + boost::scoped_ptr locker(new Mutex::Locker(mutex_)); + CondVar condvar2; // separate cond var for initial synchronization + int shared_var = 0; // let the other thread increment this + Thread t1(boost::bind(&signalAndWait, &condvar_, &condvar2, &mutex_, + &shared_var)); + Thread t2(boost::bind(&signalAndWait, &condvar_, &condvar2, &mutex_, + &shared_var)); + + // Wait until both threads are waiting on condvar_. + while (shared_var < 2 && !do_exit) { + condvar2.wait(mutex_); } + // Check we exited from the loop successfully. + ASSERT_FALSE(do_exit); + ASSERT_EQ(2, shared_var); + + // release the lock, wake up both threads, wait for them to die, and + // confirm they successfully woke up. + locker.reset(); + condvar_.signal(); + condvar_.signal(); + t1.wait(); + t2.wait(); + EXPECT_EQ(4, shared_var); +} + +void +waiter(CondVar* condver, Mutex* mutex) { + Mutex::Locker locker(*mutex); + condver->wait(*mutex); +} + +// Similar to the previous version of the same function, but just do +// condvar operations. It will never wake up. +void +signalAndWait(CondVar* condvar, Mutex* mutex) { + Mutex::Locker locker(*mutex); + condvar->signal(); + condvar->wait(*mutex); +} + +#ifdef EXPECT_DEATH +TEST_F(CondVarTest, bad) { + // We'll destroy a CondVar object while the thread is still waiting + // on it. This will trigger an assertion failure. + EXPECT_DEATH({ + CondVar cond; + Mutex::Locker locker(mutex_); + Thread t(boost::bind(&signalAndWait, &cond, &mutex_)); + cond.wait(mutex_); + }, ""); +} +#endif + +TEST_F(CondVarTest, badWait) { + // In our implementation, wait() requires acquiring the lock beforehand. + EXPECT_THROW(condvar_.wait(mutex_), isc::InvalidOperation); +} + +TEST_F(CondVarTest, emptySignal) { + // It's okay to call signal when no one waits. + EXPECT_NO_THROW(condvar_.signal()); } } From 6962458ec49390d007dbf0fa9d5d3befa53deb23 Mon Sep 17 00:00:00 2001 From: JINMEI Tatuya Date: Wed, 10 Oct 2012 22:55:34 -0700 Subject: [PATCH 07/19] [2332] added class documentation --- src/lib/util/threads/lock.h | 67 +++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/src/lib/util/threads/lock.h b/src/lib/util/threads/lock.h index baa3fa4665..c219abbdff 100644 --- a/src/lib/util/threads/lock.h +++ b/src/lib/util/threads/lock.h @@ -131,11 +131,78 @@ private: void unlock(); }; +/// \brief Encapsulation for a condition variable. +/// +/// This class provides a simple encapsulation of condition variable for +/// inter-thread synchronization. It has similar but simplified interface as +/// that for \c pthread_bond_ variants. +/// +/// It uses the \c Mutex class object for the mutex used with the condition +/// variable. Since for normal applications the internal \c Mutex::Locker +/// class is the only available interface to acquire a lock, sample code +/// for waiting on a condition variable would look like this: +/// \code +/// CondVar cond; +/// Mutex mutex; +/// { +/// Mutex::Locker locker(mutex); +/// while (some_condition) { +/// cond.wait(mutex); +/// } +/// // do something under the protection of locker +/// } // lock is released here +/// \endcode +/// Note that \c mutex passed to the \c wait() method must be the same one +/// used to construct the \c locker. +/// +/// \note This class is defined as a friend class of \c Mutex and directly +/// refers to and modifies private internals of the \c Mutex class. It breaks +/// the assumption that the lock is only acquired or released via the +/// \c Locker class and breaks other integrity assumption on \c Mutex, +/// thereby making it more fragile, but we couldn't find other way to +/// implement a safe and still simple realization of condition variables. +/// So, this is a kind of compromise. If this class is needed to be +/// extended, first consider a way to use public interfaces of \c Mutex; +/// do not easily rely on the fact that this class is a friend of it. class CondVar : boost::noncopyable { public: + /// \brief Constructor. + /// + /// \throw std::bad_alloc memory allocation failure + /// \throw isc::Unexpected other unexpected shortage of system resource CondVar(); + + /// \brief Destructor. + /// + /// An object of this class must not be destructed while some thread + /// is waiting on it. If this condition isn't met the destructor will + /// terminate the program. ~CondVar(); + + /// \brief Wait on the condition variable. + /// + /// This method works like \c pthread_cond_wait(). For mutex it takes + /// an \c Mutex class object. Unlike \c pthread_cond_wait(), however, + /// this method requires a lock for the mutex has been acquired. + /// If this condition isn't met, it can throw an exception (in the + /// debug mode build) or result in undefined behavior. + /// + /// The lock will be automatically released within this method, and + /// will be re-acquired on the exit of this method. + /// + /// \throw isc::InvalidOperation mutex isn't locked + /// \throw isc::BadValue mutex is not a valid \c Mutex object + /// + /// \param mutex A \c Mutex object to be released on wait(). void wait(Mutex& mutex); + + /// \brief Unblock a thread waiting for the condition variable. + /// + /// This method waits one of other threads (if any) waiting on this object + /// via the \c wait() call. + /// + /// This method never throws; if some unexpected low level error happens + /// it terminates the program. void signal(); private: class Impl; From dc5492b8401c85daf1b0c8801e497bac3d5eeea5 Mon Sep 17 00:00:00 2001 From: JINMEI Tatuya Date: Wed, 10 Oct 2012 22:58:39 -0700 Subject: [PATCH 08/19] [2332] (unrelated) cleanup: removed unnecesary failure case in Locker. We don't have to worry about the case lock() throws in the constructor. In that case the destructor won't be called. This simplification will make the code simpler, and we can also make mutex_ member variable a const. --- src/lib/util/threads/lock.h | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/lib/util/threads/lock.h b/src/lib/util/threads/lock.h index c219abbdff..8a072f10d3 100644 --- a/src/lib/util/threads/lock.h +++ b/src/lib/util/threads/lock.h @@ -85,26 +85,19 @@ public: /// means an attempt to use the mutex in a wrong way (locking /// a mutex second time from the same thread, for example). Locker(Mutex& mutex) : - mutex_(NULL) + mutex_(&mutex) { - // Set the mutex_ after we acquire the lock. This is because of - // exception safety. If lock() throws, it didn't work, so we must - // not unlock when we are destroyed. In such case, mutex_ is - // NULL and checked in the destructor. mutex.lock(); - mutex_ = &mutex; } /// \brief Destructor. /// /// Unlocks the mutex. ~Locker() { - if (mutex_ != NULL) { - mutex_->unlock(); - } + mutex_->unlock(); } private: - Mutex* mutex_; + Mutex* const mutex_; }; /// \brief If the mutex is currently locked /// From ca61588dc2c1ad17200416ac7f07ac272adc8903 Mon Sep 17 00:00:00 2001 From: JINMEI Tatuya Date: Wed, 10 Oct 2012 23:01:23 -0700 Subject: [PATCH 09/19] [2332] (unrelated) style cleanups: func name convention, () after sizeof. --- src/lib/util/threads/tests/lock_unittest.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/util/threads/tests/lock_unittest.cc b/src/lib/util/threads/tests/lock_unittest.cc index 0b4d3ce4ec..7e6fb53df7 100644 --- a/src/lib/util/threads/tests/lock_unittest.cc +++ b/src/lib/util/threads/tests/lock_unittest.cc @@ -80,13 +80,13 @@ performIncrement(volatile double* canary, volatile bool* ready_me, } void -no_handler(int) {} +noHandler(int) {} TEST(MutexTest, swarm) { // Create a timeout in case something got stuck here struct sigaction ignored, original; - memset(&ignored, 0, sizeof ignored); - ignored.sa_handler = no_handler; + memset(&ignored, 0, sizeof(ignored)); + ignored.sa_handler = noHandler; if (sigaction(SIGALRM, &ignored, &original)) { FAIL() << "Couldn't set alarm"; } From d3983e1e68f66bbf6c69838aebe01a8f95b7bc33 Mon Sep 17 00:00:00 2001 From: JINMEI Tatuya Date: Fri, 12 Oct 2012 14:32:22 -0700 Subject: [PATCH 10/19] [2332] missing cleanup: removed an unused function. --- src/lib/util/threads/tests/condvar_unittest.cc | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/lib/util/threads/tests/condvar_unittest.cc b/src/lib/util/threads/tests/condvar_unittest.cc index 2695f842a3..4de4f856e8 100644 --- a/src/lib/util/threads/tests/condvar_unittest.cc +++ b/src/lib/util/threads/tests/condvar_unittest.cc @@ -128,12 +128,6 @@ TEST_F(CondVarTest, multiWaits) { EXPECT_EQ(4, shared_var); } -void -waiter(CondVar* condver, Mutex* mutex) { - Mutex::Locker locker(*mutex); - condver->wait(*mutex); -} - // Similar to the previous version of the same function, but just do // condvar operations. It will never wake up. void From d504c06cbe387363d11ae091eeaa980444cc5190 Mon Sep 17 00:00:00 2001 From: JINMEI Tatuya Date: Mon, 15 Oct 2012 11:14:56 -0700 Subject: [PATCH 11/19] [2332] use EXPECT_DEATH_IF_SUPPORTED instead of ifdef. avoiding ifdef is generally better, and _IF_SUPPORTED seems to have been supported since googletest 1.4 and should be commonly available for us. --- src/lib/util/threads/tests/condvar_unittest.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/lib/util/threads/tests/condvar_unittest.cc b/src/lib/util/threads/tests/condvar_unittest.cc index 4de4f856e8..bd9adbf0e0 100644 --- a/src/lib/util/threads/tests/condvar_unittest.cc +++ b/src/lib/util/threads/tests/condvar_unittest.cc @@ -137,18 +137,16 @@ signalAndWait(CondVar* condvar, Mutex* mutex) { condvar->wait(*mutex); } -#ifdef EXPECT_DEATH TEST_F(CondVarTest, bad) { // We'll destroy a CondVar object while the thread is still waiting // on it. This will trigger an assertion failure. - EXPECT_DEATH({ + EXPECT_DEATH_IF_SUPPORTED({ CondVar cond; Mutex::Locker locker(mutex_); Thread t(boost::bind(&signalAndWait, &cond, &mutex_)); cond.wait(mutex_); }, ""); } -#endif TEST_F(CondVarTest, badWait) { // In our implementation, wait() requires acquiring the lock beforehand. From b6d2a03ff5dfc0b1269e69e44defb2999e8a5d33 Mon Sep 17 00:00:00 2001 From: JINMEI Tatuya Date: Mon, 15 Oct 2012 11:17:21 -0700 Subject: [PATCH 12/19] [2332] renamed a too-short test name a possibly better one --- src/lib/util/threads/tests/condvar_unittest.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/util/threads/tests/condvar_unittest.cc b/src/lib/util/threads/tests/condvar_unittest.cc index bd9adbf0e0..57cc5d6d5a 100644 --- a/src/lib/util/threads/tests/condvar_unittest.cc +++ b/src/lib/util/threads/tests/condvar_unittest.cc @@ -137,7 +137,7 @@ signalAndWait(CondVar* condvar, Mutex* mutex) { condvar->wait(*mutex); } -TEST_F(CondVarTest, bad) { +TEST_F(CondVarTest, destroyWhileWait) { // We'll destroy a CondVar object while the thread is still waiting // on it. This will trigger an assertion failure. EXPECT_DEATH_IF_SUPPORTED({ From 671005eea2c18ad34bb0bad435b538447cdc7a50 Mon Sep 17 00:00:00 2001 From: JINMEI Tatuya Date: Mon, 15 Oct 2012 11:21:47 -0700 Subject: [PATCH 13/19] [2332] changed the type of Locker::mutex_ to a reference. may not be a big deal in such a simple case, but just as suggested in review. --- src/lib/util/threads/lock.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/util/threads/lock.h b/src/lib/util/threads/lock.h index 8a072f10d3..16b386fb7d 100644 --- a/src/lib/util/threads/lock.h +++ b/src/lib/util/threads/lock.h @@ -85,7 +85,7 @@ public: /// means an attempt to use the mutex in a wrong way (locking /// a mutex second time from the same thread, for example). Locker(Mutex& mutex) : - mutex_(&mutex) + mutex_(mutex) { mutex.lock(); } @@ -94,10 +94,10 @@ public: /// /// Unlocks the mutex. ~Locker() { - mutex_->unlock(); + mutex_.unlock(); } private: - Mutex* const mutex_; + Mutex& mutex_; }; /// \brief If the mutex is currently locked /// From 7f94f671e0da9c98cabcc38433852732294bee4a Mon Sep 17 00:00:00 2001 From: JINMEI Tatuya Date: Mon, 15 Oct 2012 13:31:04 -0700 Subject: [PATCH 14/19] [2332] Make sure preUnlockAction() doesn't throw when it shouldn't. adding a parameter to control that. --- src/lib/util/threads/lock.cc | 13 +++++++++---- src/lib/util/threads/lock.h | 7 ++++++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/lib/util/threads/lock.cc b/src/lib/util/threads/lock.cc index 13d0a0d671..3f4d92ada6 100644 --- a/src/lib/util/threads/lock.cc +++ b/src/lib/util/threads/lock.cc @@ -128,9 +128,14 @@ Mutex::lock() { } void -Mutex::preUnlockAction() { +Mutex::preUnlockAction(bool throw_ok) { if (impl_->locked_count == 0) { - isc_throw(isc::InvalidOperation, "Unlock attempt for unlocked mutex"); + if (throw_ok) { + isc_throw(isc::InvalidOperation, + "Unlock attempt for unlocked mutex"); + } else { + assert(false); + } } --impl_->locked_count; } @@ -138,7 +143,7 @@ Mutex::preUnlockAction() { void Mutex::unlock() { assert(impl_ != NULL); - preUnlockAction(); // Only in debug mode + preUnlockAction(false); // Only in debug mode. Ensure no throw. const int result = pthread_mutex_unlock(&impl_->mutex); assert(result == 0); // This should never be possible } @@ -181,7 +186,7 @@ CondVar::~CondVar() { void CondVar::wait(Mutex& mutex) { - mutex.preUnlockAction(); // Only in debug mode + mutex.preUnlockAction(true); // Only in debug mode const int result = pthread_cond_wait(&impl_->cond_, &mutex.impl_->mutex); mutex.postLockAction(); // Only in debug mode diff --git a/src/lib/util/threads/lock.h b/src/lib/util/threads/lock.h index 16b386fb7d..25247c17f8 100644 --- a/src/lib/util/threads/lock.h +++ b/src/lib/util/threads/lock.h @@ -116,7 +116,12 @@ private: // Commonly called before releasing the lock, checking and updating // internal state for debug. - void preUnlockAction(); + // + // If throw_ok is true, it throws \c isc::InvalidOperation when the check + // fails; otherwise it aborts the process. This parameter must be set + // to false if the call to this shouldn't result in an exception (e.g. + // when called from a destructor). + void preUnlockAction(bool throw_ok); class Impl; Impl* impl_; From 410987bf3c9299053c07aee46591193c97af6ea4 Mon Sep 17 00:00:00 2001 From: JINMEI Tatuya Date: Mon, 15 Oct 2012 13:39:32 -0700 Subject: [PATCH 15/19] [2332] updated doc for wait() on what should happen if mutex isn't locked. mentioning pthread_cond_wait() seems to be confusing, so I'd rather just describing what this method does. --- src/lib/util/threads/lock.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/lib/util/threads/lock.h b/src/lib/util/threads/lock.h index 25247c17f8..89284a1b8f 100644 --- a/src/lib/util/threads/lock.h +++ b/src/lib/util/threads/lock.h @@ -180,10 +180,9 @@ public: /// \brief Wait on the condition variable. /// /// This method works like \c pthread_cond_wait(). For mutex it takes - /// an \c Mutex class object. Unlike \c pthread_cond_wait(), however, - /// this method requires a lock for the mutex has been acquired. - /// If this condition isn't met, it can throw an exception (in the - /// debug mode build) or result in undefined behavior. + /// an \c Mutex class object. A lock for the mutex must have been + /// acquired. If this condition isn't met, it can throw an exception + /// (in the debug mode build) or result in undefined behavior. /// /// The lock will be automatically released within this method, and /// will be re-acquired on the exit of this method. From a439004524335feb296ee7477a5b450a2a7d7953 Mon Sep 17 00:00:00 2001 From: JINMEI Tatuya Date: Mon, 15 Oct 2012 13:42:24 -0700 Subject: [PATCH 16/19] [2332] fixing typos and wording in doc --- src/lib/util/threads/lock.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/util/threads/lock.h b/src/lib/util/threads/lock.h index 89284a1b8f..3736c511a2 100644 --- a/src/lib/util/threads/lock.h +++ b/src/lib/util/threads/lock.h @@ -133,7 +133,7 @@ private: /// /// This class provides a simple encapsulation of condition variable for /// inter-thread synchronization. It has similar but simplified interface as -/// that for \c pthread_bond_ variants. +/// that for \c pthread_cond_ variants. /// /// It uses the \c Mutex class object for the mutex used with the condition /// variable. Since for normal applications the internal \c Mutex::Locker @@ -172,7 +172,7 @@ public: /// \brief Destructor. /// - /// An object of this class must not be destructed while some thread + /// An object of this class must not be destroyed while some thread /// is waiting on it. If this condition isn't met the destructor will /// terminate the program. ~CondVar(); @@ -195,7 +195,7 @@ public: /// \brief Unblock a thread waiting for the condition variable. /// - /// This method waits one of other threads (if any) waiting on this object + /// This method wakes one of other threads (if any) waiting on this object /// via the \c wait() call. /// /// This method never throws; if some unexpected low level error happens From 8c02f8a83f011816c3fb19f655a1e57edf0c1048 Mon Sep 17 00:00:00 2001 From: JINMEI Tatuya Date: Mon, 15 Oct 2012 13:45:53 -0700 Subject: [PATCH 17/19] [2332] added comments about missing pthread_cond_xxx variants --- src/lib/util/threads/lock.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/lib/util/threads/lock.h b/src/lib/util/threads/lock.h index 3736c511a2..cb3805ecb1 100644 --- a/src/lib/util/threads/lock.h +++ b/src/lib/util/threads/lock.h @@ -153,6 +153,12 @@ private: /// Note that \c mutex passed to the \c wait() method must be the same one /// used to construct the \c locker. /// +/// Right now there is no equivalent to pthread_cond_broadcast() or +/// pthread_cond_timedwait() in this class, because this class is meant +/// for internal development of BIND 10 and we don't need these at the +/// moment. If and when we need these interfaces they can be added at that +/// point. +/// /// \note This class is defined as a friend class of \c Mutex and directly /// refers to and modifies private internals of the \c Mutex class. It breaks /// the assumption that the lock is only acquired or released via the From c450d77e81322fb6a3c6753d721f5d3bb62fff71 Mon Sep 17 00:00:00 2001 From: JINMEI Tatuya Date: Wed, 17 Oct 2012 08:59:58 -0700 Subject: [PATCH 18/19] [2332] changed one exception to assert() based on review discussion --- src/lib/util/threads/lock.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/lib/util/threads/lock.cc b/src/lib/util/threads/lock.cc index 3f4d92ada6..5f66c10d73 100644 --- a/src/lib/util/threads/lock.cc +++ b/src/lib/util/threads/lock.cc @@ -111,9 +111,10 @@ Mutex::~Mutex() { void Mutex::postLockAction() { - if (impl_->locked_count != 0) { - isc_throw(isc::InvalidOperation, "Lock attempt for locked mutex"); - } + // This assertion would fail only in non-debugging mode, in which case + // this method wouldn't be called either, so we simply assert the + // condition. + assert(impl_->locked_count == 0); ++impl_->locked_count; } From 650655fd267d652ec1b0d5e57a261ab767ada447 Mon Sep 17 00:00:00 2001 From: JINMEI Tatuya Date: Wed, 17 Oct 2012 09:05:37 -0700 Subject: [PATCH 19/19] [2332] renamed thread/lock.h to thread/sync.h as it's not only for locks now --- src/bin/auth/auth_srv.cc | 2 +- src/bin/auth/benchmarks/query_bench.cc | 2 +- src/bin/auth/command.cc | 2 +- src/bin/auth/main.cc | 2 +- src/bin/auth/tests/auth_srv_unittest.cc | 2 +- src/bin/auth/tests/command_unittest.cc | 2 +- src/bin/auth/tests/datasrc_config_unittest.cc | 2 +- src/lib/util/threads/Makefile.am | 2 +- src/lib/util/threads/{lock.cc => sync.cc} | 2 +- src/lib/util/threads/{lock.h => sync.h} | 4 ++-- src/lib/util/threads/tests/condvar_unittest.cc | 2 +- src/lib/util/threads/tests/lock_unittest.cc | 2 +- src/lib/util/threads/thread.cc | 2 +- 13 files changed, 14 insertions(+), 14 deletions(-) rename src/lib/util/threads/{lock.cc => sync.cc} (99%) rename src/lib/util/threads/{lock.h => sync.h} (99%) diff --git a/src/bin/auth/auth_srv.cc b/src/bin/auth/auth_srv.cc index e73eb528db..315a7527de 100644 --- a/src/bin/auth/auth_srv.cc +++ b/src/bin/auth/auth_srv.cc @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include diff --git a/src/bin/auth/benchmarks/query_bench.cc b/src/bin/auth/benchmarks/query_bench.cc index 37976a3358..44aeb8da8e 100644 --- a/src/bin/auth/benchmarks/query_bench.cc +++ b/src/bin/auth/benchmarks/query_bench.cc @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include diff --git a/src/bin/auth/command.cc b/src/bin/auth/command.cc index d26cf091de..efd60f2645 100644 --- a/src/bin/auth/command.cc +++ b/src/bin/auth/command.cc @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include diff --git a/src/bin/auth/main.cc b/src/bin/auth/main.cc index 99080662ff..27ac04aea2 100644 --- a/src/bin/auth/main.cc +++ b/src/bin/auth/main.cc @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include diff --git a/src/bin/auth/tests/auth_srv_unittest.cc b/src/bin/auth/tests/auth_srv_unittest.cc index e248e81483..396b247491 100644 --- a/src/bin/auth/tests/auth_srv_unittest.cc +++ b/src/bin/auth/tests/auth_srv_unittest.cc @@ -39,7 +39,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/bin/auth/tests/command_unittest.cc b/src/bin/auth/tests/command_unittest.cc index 8aa2322151..a245c3b53b 100644 --- a/src/bin/auth/tests/command_unittest.cc +++ b/src/bin/auth/tests/command_unittest.cc @@ -16,7 +16,7 @@ #include "datasrc_util.h" -#include +#include #include #include diff --git a/src/bin/auth/tests/datasrc_config_unittest.cc b/src/bin/auth/tests/datasrc_config_unittest.cc index 877f92166f..2dc70d132f 100644 --- a/src/bin/auth/tests/datasrc_config_unittest.cc +++ b/src/bin/auth/tests/datasrc_config_unittest.cc @@ -16,7 +16,7 @@ #include #include -#include +#include #include diff --git a/src/lib/util/threads/Makefile.am b/src/lib/util/threads/Makefile.am index 7b9fb8f859..121e4ab37f 100644 --- a/src/lib/util/threads/Makefile.am +++ b/src/lib/util/threads/Makefile.am @@ -5,7 +5,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib AM_CPPFLAGS += $(BOOST_INCLUDES) $(MULTITHREADING_FLAG) lib_LTLIBRARIES = libb10-threads.la -libb10_threads_la_SOURCES = lock.h lock.cc +libb10_threads_la_SOURCES = sync.h sync.cc libb10_threads_la_SOURCES += thread.h thread.cc libb10_threads_la_LIBADD = $(top_builddir)/src/lib/exceptions/libb10-exceptions.la diff --git a/src/lib/util/threads/lock.cc b/src/lib/util/threads/sync.cc similarity index 99% rename from src/lib/util/threads/lock.cc rename to src/lib/util/threads/sync.cc index 5f66c10d73..c98a7a6b06 100644 --- a/src/lib/util/threads/lock.cc +++ b/src/lib/util/threads/sync.cc @@ -12,7 +12,7 @@ // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. -#include "lock.h" +#include "sync.h" #include diff --git a/src/lib/util/threads/lock.h b/src/lib/util/threads/sync.h similarity index 99% rename from src/lib/util/threads/lock.h rename to src/lib/util/threads/sync.h index cb3805ecb1..ff56999f99 100644 --- a/src/lib/util/threads/lock.h +++ b/src/lib/util/threads/sync.h @@ -12,8 +12,8 @@ // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. -#ifndef B10_THREAD_LOCK_H -#define B10_THREAD_LOCK_H +#ifndef B10_THREAD_SYNC_H +#define B10_THREAD_SYNC_H #include diff --git a/src/lib/util/threads/tests/condvar_unittest.cc b/src/lib/util/threads/tests/condvar_unittest.cc index 57cc5d6d5a..e3a534b55b 100644 --- a/src/lib/util/threads/tests/condvar_unittest.cc +++ b/src/lib/util/threads/tests/condvar_unittest.cc @@ -14,7 +14,7 @@ #include -#include +#include #include #include diff --git a/src/lib/util/threads/tests/lock_unittest.cc b/src/lib/util/threads/tests/lock_unittest.cc index 7e6fb53df7..4ddb6b2422 100644 --- a/src/lib/util/threads/tests/lock_unittest.cc +++ b/src/lib/util/threads/tests/lock_unittest.cc @@ -12,7 +12,7 @@ // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. -#include +#include #include #include diff --git a/src/lib/util/threads/thread.cc b/src/lib/util/threads/thread.cc index c1c9cdf028..5608e4962e 100644 --- a/src/lib/util/threads/thread.cc +++ b/src/lib/util/threads/thread.cc @@ -13,7 +13,7 @@ // PERFORMANCE OF THIS SOFTWARE. #include "thread.h" -#include "lock.h" +#include "sync.h" #include #include