From: Mukund Sivaraman Date: Sun, 21 Oct 2012 23:20:00 +0000 (+0530) Subject: [2198] Add Mutex::tryLock() and make lock methods public X-Git-Tag: trac2402_base~10^2~17 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b09b4308af92511dde35d87a23bf159b2f71848b;p=thirdparty%2Fkea.git [2198] Add Mutex::tryLock() and make lock methods public tryLock() is necessary inside InterprocessSyncFile. It also doesn't make sense afterwards to make a dynamically constructed Mutex::Locker that lives after the basic block is exited. So lock() and unlock() have also been made public. I've added comments to discourage the use of these methods directly and use the Mutex::Locker where applicable. --- diff --git a/src/lib/util/threads/sync.cc b/src/lib/util/threads/sync.cc index c98a7a6b06..db3cc33fb4 100644 --- a/src/lib/util/threads/sync.cc +++ b/src/lib/util/threads/sync.cc @@ -128,6 +128,17 @@ Mutex::lock() { postLockAction(); // Only in debug mode } +bool +Mutex::tryLock() { + assert(impl_ != NULL); + const int result = pthread_mutex_trylock(&impl_->mutex); + if (result != 0) { + return (false); + } + postLockAction(); // Only in debug mode + return (true); +} + void Mutex::preUnlockAction(bool throw_ok) { if (impl_->locked_count == 0) { diff --git a/src/lib/util/threads/sync.h b/src/lib/util/threads/sync.h index ff56999f99..642576fa87 100644 --- a/src/lib/util/threads/sync.h +++ b/src/lib/util/threads/sync.h @@ -107,6 +107,32 @@ public: /// /// \todo Disable in non-debug build bool locked() const; + + /// \brief Lock the mutex + /// + /// This method blocks until the mutex can be locked. + /// + /// Please consider not using this method directly and instead using + /// a Mutex::Locker object instead. + void lock(); + + /// \brief Try to lock the mutex + /// + /// This method doesn't block and returns immediately with a status + /// on whether the lock operation was successful. + /// + /// Please consider not using this method directly and instead using + /// a Mutex::Locker object instead. + /// + /// \return true if the lock was successful, false otherwise. + bool tryLock(); + + /// \brief Unlock the mutex + /// + /// Please consider not using this method directly and instead using + /// a Mutex::Locker object instead. + void unlock(); + private: friend class CondVar; @@ -125,8 +151,6 @@ private: class Impl; Impl* impl_; - void lock(); - void unlock(); }; /// \brief Encapsulation for a condition variable. diff --git a/src/lib/util/threads/tests/lock_unittest.cc b/src/lib/util/threads/tests/lock_unittest.cc index 9c17e6fc65..9deddd7fcf 100644 --- a/src/lib/util/threads/tests/lock_unittest.cc +++ b/src/lib/util/threads/tests/lock_unittest.cc @@ -26,6 +26,24 @@ using namespace isc::util::thread; namespace { +TEST(MutexTest, direct) { + Mutex mutex; + EXPECT_FALSE(mutex.locked()); // Debug-only build + + mutex.lock(); + EXPECT_TRUE(mutex.locked()); // Debug-only build + + EXPECT_FALSE(mutex.tryLock()); + + mutex.unlock(); + EXPECT_FALSE(mutex.locked()); // Debug-only build + + EXPECT_TRUE(mutex.tryLock()); + + mutex.unlock(); + EXPECT_FALSE(mutex.locked()); // Debug-only build +} + // If we try to lock the debug mutex multiple times, it should throw. TEST(MutexTest, lockMultiple) { // TODO: Once we support non-debug mutexes, disable the test if we compile