Browse Source

[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.
Mukund Sivaraman 12 years ago
parent
commit
e71cd13c5c

+ 11 - 0
src/lib/util/threads/lock.cc

@@ -119,6 +119,17 @@ Mutex::lock() {
     ++impl_->locked_count; // Only in debug mode
     ++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
 void
 Mutex::unlock() {
 Mutex::unlock() {
     assert(impl_ != NULL);
     assert(impl_ != NULL);

+ 27 - 2
src/lib/util/threads/lock.h

@@ -105,6 +105,7 @@ public:
     private:
     private:
         Mutex* mutex_;
         Mutex* mutex_;
     };
     };
+
     /// \brief If the mutex is currently locked
     /// \brief If the mutex is currently locked
     ///
     ///
     /// This is debug aiding method only. And it might be unavailable in
     /// This is debug aiding method only. And it might be unavailable in
@@ -113,11 +114,35 @@ public:
     ///
     ///
     /// \todo Disable in non-debug build
     /// \todo Disable in non-debug build
     bool locked() const;
     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:
 private:
     class Impl;
     class Impl;
     Impl* impl_;
     Impl* impl_;
-    void lock();
-    void unlock();
 };
 };
 
 
 
 

+ 18 - 0
src/lib/util/threads/tests/lock_unittest.cc

@@ -25,6 +25,24 @@ using namespace isc::util::thread;
 
 
 namespace {
 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.
 // If we try to lock the debug mutex multiple times, it should throw.
 TEST(MutexTest, lockMultiple) {
 TEST(MutexTest, lockMultiple) {
     // TODO: Once we support non-debug mutexes, disable the test if we compile
     // TODO: Once we support non-debug mutexes, disable the test if we compile