logging: add more documentation
[folly.git] / folly / fibers / TimedMutex-inl.h
index c11871aff68fb8ae8f4f1902a4d5e879607fea1f..dd363b8d4607dfcb8730659f361f56b984625f82 100644 (file)
@@ -15,6 +15,8 @@
  */
 #pragma once
 
+#include <mutex>
+
 namespace folly {
 namespace fibers {
 
@@ -24,7 +26,7 @@ namespace fibers {
 
 template <typename WaitFunc>
 TimedMutex::LockResult TimedMutex::lockHelper(WaitFunc&& waitFunc) {
-  std::unique_lock<folly::SpinLock> lock(lock_);
+  std::unique_lock<folly::SpinLock> ulock(lock_);
   if (!locked_) {
     locked_ = true;
     return LockResult::SUCCESS;
@@ -51,7 +53,7 @@ TimedMutex::LockResult TimedMutex::lockHelper(WaitFunc&& waitFunc) {
     threadWaiters_.push_back(waiter);
   }
 
-  lock.unlock();
+  ulock.unlock();
 
   if (!waitFunc(waiter)) {
     return LockResult::TIMEOUT;
@@ -62,7 +64,9 @@ TimedMutex::LockResult TimedMutex::lockHelper(WaitFunc&& waitFunc) {
       std::lock_guard<folly::SpinLock> lg(lock_);
 
       auto stolen = notifiedFiber_ != &waiter;
-      notifiedFiber_ = nullptr;
+      if (!stolen) {
+        notifiedFiber_ = nullptr;
+      }
       return stolen;
     }();
 
@@ -91,7 +95,7 @@ template <typename Rep, typename Period>
 bool TimedMutex::timed_lock(
     const std::chrono::duration<Rep, Period>& duration) {
   auto result = lockHelper([&](MutexWaiter& waiter) {
-    if (!waiter.baton.timed_wait(duration)) {
+    if (!waiter.baton.try_wait_for(duration)) {
       // We timed out. Two cases:
       // 1. We're still in the waiter list and we truly timed out
       // 2. We're not in the waiter list anymore. This could happen if the baton
@@ -151,11 +155,11 @@ inline void TimedMutex::unlock() {
 
 template <typename BatonType>
 void TimedRWMutex<BatonType>::read_lock() {
-  pthread_spin_lock(&lock_);
+  std::unique_lock<folly::SpinLock> ulock{lock_};
   if (state_ == State::WRITE_LOCKED) {
     MutexWaiter waiter;
     read_waiters_.push_back(waiter);
-    pthread_spin_unlock(&lock_);
+    ulock.unlock();
     waiter.baton.wait();
     assert(state_ == State::READ_LOCKED);
     return;
@@ -166,32 +170,29 @@ void TimedRWMutex<BatonType>::read_lock() {
   assert(read_waiters_.empty());
   state_ = State::READ_LOCKED;
   readers_ += 1;
-  pthread_spin_unlock(&lock_);
 }
 
 template <typename BatonType>
 template <typename Rep, typename Period>
 bool TimedRWMutex<BatonType>::timed_read_lock(
     const std::chrono::duration<Rep, Period>& duration) {
-  pthread_spin_lock(&lock_);
+  std::unique_lock<folly::SpinLock> ulock{lock_};
   if (state_ == State::WRITE_LOCKED) {
     MutexWaiter waiter;
     read_waiters_.push_back(waiter);
-    pthread_spin_unlock(&lock_);
+    ulock.unlock();
 
-    if (!waiter.baton.timed_wait(duration)) {
+    if (!waiter.baton.try_wait_for(duration)) {
       // We timed out. Two cases:
       // 1. We're still in the waiter list and we truly timed out
       // 2. We're not in the waiter list anymore. This could happen if the baton
       //    times out but the mutex is unlocked before we reach this code. In
       //    this case we'll pretend we got the lock on time.
-      pthread_spin_lock(&lock_);
+      std::lock_guard<SpinLock> guard{lock_};
       if (waiter.hook.is_linked()) {
         read_waiters_.erase(read_waiters_.iterator_to(waiter));
-        pthread_spin_unlock(&lock_);
         return false;
       }
-      pthread_spin_unlock(&lock_);
     }
     return true;
   }
@@ -201,13 +202,12 @@ bool TimedRWMutex<BatonType>::timed_read_lock(
   assert(read_waiters_.empty());
   state_ = State::READ_LOCKED;
   readers_ += 1;
-  pthread_spin_unlock(&lock_);
   return true;
 }
 
 template <typename BatonType>
 bool TimedRWMutex<BatonType>::try_read_lock() {
-  pthread_spin_lock(&lock_);
+  std::lock_guard<SpinLock> guard{lock_};
   if (state_ != State::WRITE_LOCKED) {
     assert(
         (state_ == State::UNLOCKED && readers_ == 0) ||
@@ -215,25 +215,22 @@ bool TimedRWMutex<BatonType>::try_read_lock() {
     assert(read_waiters_.empty());
     state_ = State::READ_LOCKED;
     readers_ += 1;
-    pthread_spin_unlock(&lock_);
     return true;
   }
-  pthread_spin_unlock(&lock_);
   return false;
 }
 
 template <typename BatonType>
 void TimedRWMutex<BatonType>::write_lock() {
-  pthread_spin_lock(&lock_);
+  std::unique_lock<folly::SpinLock> ulock{lock_};
   if (state_ == State::UNLOCKED) {
     verify_unlocked_properties();
     state_ = State::WRITE_LOCKED;
-    pthread_spin_unlock(&lock_);
     return;
   }
   MutexWaiter waiter;
   write_waiters_.push_back(waiter);
-  pthread_spin_unlock(&lock_);
+  ulock.unlock();
   waiter.baton.wait();
 }
 
@@ -241,30 +238,27 @@ template <typename BatonType>
 template <typename Rep, typename Period>
 bool TimedRWMutex<BatonType>::timed_write_lock(
     const std::chrono::duration<Rep, Period>& duration) {
-  pthread_spin_lock(&lock_);
+  std::unique_lock<folly::SpinLock> ulock{lock_};
   if (state_ == State::UNLOCKED) {
     verify_unlocked_properties();
     state_ = State::WRITE_LOCKED;
-    pthread_spin_unlock(&lock_);
     return true;
   }
   MutexWaiter waiter;
   write_waiters_.push_back(waiter);
-  pthread_spin_unlock(&lock_);
+  ulock.unlock();
 
-  if (!waiter.baton.timed_wait(duration)) {
+  if (!waiter.baton.try_wait_for(duration)) {
     // We timed out. Two cases:
     // 1. We're still in the waiter list and we truly timed out
     // 2. We're not in the waiter list anymore. This could happen if the baton
     //    times out but the mutex is unlocked before we reach this code. In
     //    this case we'll pretend we got the lock on time.
-    pthread_spin_lock(&lock_);
+    std::lock_guard<SpinLock> guard{lock_};
     if (waiter.hook.is_linked()) {
       write_waiters_.erase(write_waiters_.iterator_to(waiter));
-      pthread_spin_unlock(&lock_);
       return false;
     }
-    pthread_spin_unlock(&lock_);
   }
   assert(state_ == State::WRITE_LOCKED);
   return true;
@@ -272,20 +266,18 @@ bool TimedRWMutex<BatonType>::timed_write_lock(
 
 template <typename BatonType>
 bool TimedRWMutex<BatonType>::try_write_lock() {
-  pthread_spin_lock(&lock_);
+  std::lock_guard<SpinLock> guard{lock_};
   if (state_ == State::UNLOCKED) {
     verify_unlocked_properties();
     state_ = State::WRITE_LOCKED;
-    pthread_spin_unlock(&lock_);
     return true;
   }
-  pthread_spin_unlock(&lock_);
   return false;
 }
 
 template <typename BatonType>
 void TimedRWMutex<BatonType>::unlock() {
-  pthread_spin_lock(&lock_);
+  std::lock_guard<SpinLock> guard{lock_};
   assert(state_ != State::UNLOCKED);
   assert(
       (state_ == State::READ_LOCKED && readers_ > 0) ||
@@ -322,12 +314,11 @@ void TimedRWMutex<BatonType>::unlock() {
   } else {
     assert(state_ == State::READ_LOCKED);
   }
-  pthread_spin_unlock(&lock_);
 }
 
 template <typename BatonType>
 void TimedRWMutex<BatonType>::downgrade() {
-  pthread_spin_lock(&lock_);
+  std::lock_guard<SpinLock> guard{lock_};
   assert(state_ == State::WRITE_LOCKED && readers_ == 0);
   state_ = State::READ_LOCKED;
   readers_ += 1;
@@ -341,7 +332,6 @@ void TimedRWMutex<BatonType>::downgrade() {
       to_wake.baton.post();
     }
   }
-  pthread_spin_unlock(&lock_);
-}
-}
 }
+} // namespace fibers
+} // namespace folly