THRIFT ReadWriteMutex

Summary: Implemented a read/write lock class in thrift::concurrency

Reviewed By: marc

Test Plan: I compiled this, then compiled a version of fb303 that uses this
(future checkin pending further tests), then ran a binary using the new fb303
and it didn't crash as things were added to the map using the ReadWriteMutex

Revert Plan: yup

Notes: this should replace rw_lock.h for most clients


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665154 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cpp/src/concurrency/Mutex.cpp b/lib/cpp/src/concurrency/Mutex.cpp
index 5993ea1..8f79795 100644
--- a/lib/cpp/src/concurrency/Mutex.cpp
+++ b/lib/cpp/src/concurrency/Mutex.cpp
@@ -48,5 +48,54 @@
 
 void Mutex::unlock() const { impl_->unlock(); }
 
+/** 
+ * Implementation of ReadWriteMutex class using POSIX rw lock
+ *
+ * @author boz
+ * @version $Id:$
+ */
+class ReadWriteMutex::impl {
+public:
+  impl() : initialized_(false) {
+    int ret = pthread_rwlock_init(&rw_lock_, NULL);
+    assert(ret == 0);
+    initialized_ = true;
+  }
+
+  ~impl() {
+    if(initialized_) {
+      initialized_ = false;
+      int ret = pthread_rwlock_destroy(&rw_lock_);
+      assert(ret == 0);
+    }
+  }
+
+  void acquireRead() const { pthread_rwlock_rdlock(&rw_lock_); }
+
+  void acquireWrite() const { pthread_rwlock_wrlock(&rw_lock_); }
+
+  bool attemptRead() const { return pthread_rwlock_tryrdlock(&rw_lock_); }
+
+  bool attemptWrite() const { return pthread_rwlock_trywrlock(&rw_lock_); }
+
+  void release() const { pthread_rwlock_unlock(&rw_lock_); }
+
+private: 
+  mutable pthread_rwlock_t rw_lock_;
+  mutable bool initialized_;
+};
+
+ReadWriteMutex::ReadWriteMutex() : impl_(new ReadWriteMutex::impl()) {}
+
+void ReadWriteMutex::acquireRead() const { impl_->acquireRead(); }
+
+void ReadWriteMutex::acquireWrite() const { impl_->acquireWrite(); }
+
+bool ReadWriteMutex::attemptRead() const { return impl_->attemptRead(); }
+
+bool ReadWriteMutex::attemptWrite() const { return impl_->attemptWrite(); }
+
+void ReadWriteMutex::release() const { impl_->release(); }
+
 }}} // facebook::thrift::concurrency
 
diff --git a/lib/cpp/src/concurrency/Mutex.h b/lib/cpp/src/concurrency/Mutex.h
index 620b340..d4788b3 100644
--- a/lib/cpp/src/concurrency/Mutex.h
+++ b/lib/cpp/src/concurrency/Mutex.h
@@ -27,12 +27,33 @@
   impl* impl_;
 };
 
-class MutexMonitor {
+class ReadWriteMutex {
+public:
+  ReadWriteMutex();
+  virtual ~ReadWriteMutex() {}
+
+  // these get the lock and block until it is done successfully
+  virtual void acquireRead() const;
+  virtual void acquireWrite() const;
+
+  // these attempt to get the lock, returning false immediately if they fail
+  virtual bool attemptRead() const;
+  virtual bool attemptWrite() const;
+
+  // this releases both read and write locks
+  virtual void release() const;
+   
+private:
+  class impl;
+  impl* impl_;
+};
+
+class Guard{
  public: 
-  MutexMonitor(const Mutex& value) : mutex_(value) {
+  Guard(const Mutex& value) : mutex_(value) {
     mutex_.lock();
   }
-  ~MutexMonitor() {
+  ~Guard() {
     mutex_.unlock();
   }