From: Mukund Sivaraman Date: Tue, 9 Oct 2012 21:33:09 +0000 (+0530) Subject: [2198] Add Mutex::tryLock() and make lock methods public X-Git-Tag: trac2402_base~28^2~12 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e71cd13c5cb261635f7115e0d30fbd7dcc5fe151;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/lock.cc b/src/lib/util/threads/lock.cc index 6a165aa531..ab6bd797df 100644 --- a/src/lib/util/threads/lock.cc +++ b/src/lib/util/threads/lock.cc @@ -119,6 +119,17 @@ Mutex::lock() { ++impl_->locked_count; // Only in debug mode } +bool +Mutex::tryLock() { + assert(impl_ != NULL); + const int result = pthread_mutex_trylock(&impl_->mutex); + if (result != 0) { + return (false); + } + ++impl_->locked_count; // Only in debug mode + return (true); +} + void Mutex::unlock() { assert(impl_ != NULL); diff --git a/src/lib/util/threads/lock.h b/src/lib/util/threads/lock.h index fef537b9a5..8426a1aa67 100644 --- a/src/lib/util/threads/lock.h +++ b/src/lib/util/threads/lock.h @@ -105,6 +105,7 @@ public: private: Mutex* mutex_; }; + /// \brief If the mutex is currently locked /// /// This is debug aiding method only. And it might be unavailable in @@ -113,11 +114,35 @@ 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: class Impl; Impl* impl_; - void lock(); - void unlock(); }; diff --git a/src/lib/util/threads/tests/lock_unittest.cc b/src/lib/util/threads/tests/lock_unittest.cc index 0b4d3ce4ec..7e15a2025c 100644 --- a/src/lib/util/threads/tests/lock_unittest.cc +++ b/src/lib/util/threads/tests/lock_unittest.cc @@ -25,6 +25,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