proxygen
folly::fibers::TimedRWMutex< BatonType > Class Template Reference

#include <TimedMutex.h>

Classes

struct  MutexWaiter
 
class  ReadHolder
 
class  WriteHolder
 

Public Member Functions

 TimedRWMutex ()=default
 
 ~TimedRWMutex ()=default
 
 TimedRWMutex (const TimedRWMutex &rhs)=delete
 
TimedRWMutexoperator= (const TimedRWMutex &rhs)=delete
 
 TimedRWMutex (TimedRWMutex &&rhs)=delete
 
TimedRWMutexoperator= (TimedRWMutex &&rhs)=delete
 
void read_lock ()
 
template<typename Rep , typename Period >
bool timed_read_lock (const std::chrono::duration< Rep, Period > &duration)
 
bool try_read_lock ()
 
void write_lock ()
 
template<typename Rep , typename Period >
bool timed_write_lock (const std::chrono::duration< Rep, Period > &duration)
 
bool try_write_lock ()
 
void lock ()
 
void unlock ()
 
void downgrade ()
 

Private Types

enum  State { State::UNLOCKED, State::READ_LOCKED, State::WRITE_LOCKED }
 
typedef boost::intrusive::list_member_hook MutexWaiterHookType
 
typedef boost::intrusive::member_hook< MutexWaiter, MutexWaiterHookType,&MutexWaiter::hookMutexWaiterHook
 
typedef boost::intrusive::list< MutexWaiter, MutexWaiterHook, boost::intrusive::constant_time_size< true > > MutexWaiterList
 

Private Member Functions

void verify_unlocked_properties ()
 

Private Attributes

folly::SpinLock lock_
 
State state_ = State::UNLOCKED
 
uint32_t readers_ = 0
 
MutexWaiterList write_waiters_
 
MutexWaiterList read_waiters_
 

Detailed Description

template<typename BatonType>
class folly::fibers::TimedRWMutex< BatonType >

A readers-writer lock which allows multiple readers to hold the lock simultaneously or only one writer.

NOTE: This is a reader-preferred RWLock i.e. readers are give priority when there are both readers and writers waiting to get the lock.

Definition at line 92 of file TimedMutex.h.

Member Typedef Documentation

template<typename BatonType >
typedef boost::intrusive:: member_hook<MutexWaiter, MutexWaiterHookType, &MutexWaiter::hook> folly::fibers::TimedRWMutex< BatonType >::MutexWaiterHook
private

Definition at line 211 of file TimedMutex.h.

template<typename BatonType >
typedef boost::intrusive::list_member_hook folly::fibers::TimedRWMutex< BatonType >::MutexWaiterHookType
private

Definition at line 201 of file TimedMutex.h.

template<typename BatonType >
typedef boost::intrusive::list< MutexWaiter, MutexWaiterHook, boost::intrusive::constant_time_size<true> > folly::fibers::TimedRWMutex< BatonType >::MutexWaiterList
private

Definition at line 217 of file TimedMutex.h.

Member Enumeration Documentation

template<typename BatonType >
enum folly::fibers::TimedRWMutex::State
strongprivate
Enumerator
UNLOCKED 
READ_LOCKED 
WRITE_LOCKED 

Definition at line 195 of file TimedMutex.h.

195  {
196  UNLOCKED,
197  READ_LOCKED,
198  WRITE_LOCKED,
199  };

Constructor & Destructor Documentation

template<typename BatonType >
folly::fibers::TimedRWMutex< BatonType >::TimedRWMutex ( )
default
template<typename BatonType >
folly::fibers::TimedRWMutex< BatonType >::~TimedRWMutex ( )
default
template<typename BatonType >
folly::fibers::TimedRWMutex< BatonType >::TimedRWMutex ( const TimedRWMutex< BatonType > &  rhs)
delete
template<typename BatonType >
folly::fibers::TimedRWMutex< BatonType >::TimedRWMutex ( TimedRWMutex< BatonType > &&  rhs)
delete

Member Function Documentation

template<typename BatonType >
void folly::fibers::TimedRWMutex< BatonType >::downgrade ( )

Definition at line 320 of file TimedMutex-inl.h.

References folly::fibers::TimedRWMutex< BatonType >::MutexWaiter::baton, folly::gen::guard(), and folly::fibers::TimedMutex::lock_.

320  {
321  std::lock_guard<SpinLock> guard{lock_};
322  assert(state_ == State::WRITE_LOCKED && readers_ == 0);
324  readers_ += 1;
325 
326  if (!read_waiters_.empty()) {
327  readers_ += read_waiters_.size();
328 
329  while (!read_waiters_.empty()) {
330  MutexWaiter& to_wake = read_waiters_.front();
331  read_waiters_.pop_front();
332  to_wake.baton.post();
333  }
334  }
335 }
MutexWaiterList read_waiters_
Definition: TimedMutex.h:228
GuardImpl guard(ErrorHandler &&handler)
Definition: Base.h:840
template<typename BatonType >
void folly::fibers::TimedRWMutex< BatonType >::lock ( )
inline

Definition at line 131 of file TimedMutex.h.

References folly::fibers::TimedMutex::unlock().

131  {
132  write_lock();
133  }
template<typename BatonType >
TimedRWMutex& folly::fibers::TimedRWMutex< BatonType >::operator= ( const TimedRWMutex< BatonType > &  rhs)
delete
template<typename BatonType >
TimedRWMutex& folly::fibers::TimedRWMutex< BatonType >::operator= ( TimedRWMutex< BatonType > &&  rhs)
delete
template<typename BatonType >
void folly::fibers::TimedRWMutex< BatonType >::read_lock ( )

Definition at line 157 of file TimedMutex-inl.h.

References folly::fibers::TimedRWMutex< BatonType >::MutexWaiter::baton, folly::fibers::TimedMutex::lock_, and folly::ulock().

157  {
158  std::unique_lock<folly::SpinLock> ulock{lock_};
159  if (state_ == State::WRITE_LOCKED) {
160  MutexWaiter waiter;
161  read_waiters_.push_back(waiter);
162  ulock.unlock();
163  waiter.baton.wait();
164  assert(state_ == State::READ_LOCKED);
165  return;
166  }
167  assert(
168  (state_ == State::UNLOCKED && readers_ == 0) ||
169  (state_ == State::READ_LOCKED && readers_ > 0));
170  assert(read_waiters_.empty());
172  readers_ += 1;
173 }
MutexWaiterList read_waiters_
Definition: TimedMutex.h:228
auto ulock(Synchronized< D, M > &synchronized, Args &&...args)
template<typename BatonType >
template<typename Rep , typename Period >
bool folly::fibers::TimedRWMutex< BatonType >::timed_read_lock ( const std::chrono::duration< Rep, Period > &  duration)

Definition at line 177 of file TimedMutex-inl.h.

References folly::fibers::TimedRWMutex< BatonType >::MutexWaiter::baton, folly::gen::guard(), folly::fibers::TimedRWMutex< BatonType >::MutexWaiter::hook, folly::fibers::TimedMutex::lock_, and folly::ulock().

178  {
179  std::unique_lock<folly::SpinLock> ulock{lock_};
180  if (state_ == State::WRITE_LOCKED) {
181  MutexWaiter waiter;
182  read_waiters_.push_back(waiter);
183  ulock.unlock();
184 
185  if (!waiter.baton.try_wait_for(duration)) {
186  // We timed out. Two cases:
187  // 1. We're still in the waiter list and we truly timed out
188  // 2. We're not in the waiter list anymore. This could happen if the baton
189  // times out but the mutex is unlocked before we reach this code. In
190  // this case we'll pretend we got the lock on time.
191  std::lock_guard<SpinLock> guard{lock_};
192  if (waiter.hook.is_linked()) {
193  read_waiters_.erase(read_waiters_.iterator_to(waiter));
194  return false;
195  }
196  }
197  return true;
198  }
199  assert(
200  (state_ == State::UNLOCKED && readers_ == 0) ||
201  (state_ == State::READ_LOCKED && readers_ > 0));
202  assert(read_waiters_.empty());
204  readers_ += 1;
205  return true;
206 }
MutexWaiterList read_waiters_
Definition: TimedMutex.h:228
GuardImpl guard(ErrorHandler &&handler)
Definition: Base.h:840
auto ulock(Synchronized< D, M > &synchronized, Args &&...args)
template<typename BatonType >
template<typename Rep , typename Period >
bool folly::fibers::TimedRWMutex< BatonType >::timed_write_lock ( const std::chrono::duration< Rep, Period > &  duration)

Definition at line 239 of file TimedMutex-inl.h.

References folly::fibers::TimedRWMutex< BatonType >::MutexWaiter::baton, folly::gen::guard(), folly::fibers::TimedRWMutex< BatonType >::MutexWaiter::hook, folly::fibers::TimedMutex::lock_, and folly::ulock().

240  {
241  std::unique_lock<folly::SpinLock> ulock{lock_};
242  if (state_ == State::UNLOCKED) {
245  return true;
246  }
247  MutexWaiter waiter;
248  write_waiters_.push_back(waiter);
249  ulock.unlock();
250 
251  if (!waiter.baton.try_wait_for(duration)) {
252  // We timed out. Two cases:
253  // 1. We're still in the waiter list and we truly timed out
254  // 2. We're not in the waiter list anymore. This could happen if the baton
255  // times out but the mutex is unlocked before we reach this code. In
256  // this case we'll pretend we got the lock on time.
257  std::lock_guard<SpinLock> guard{lock_};
258  if (waiter.hook.is_linked()) {
259  write_waiters_.erase(write_waiters_.iterator_to(waiter));
260  return false;
261  }
262  }
263  assert(state_ == State::WRITE_LOCKED);
264  return true;
265 }
MutexWaiterList write_waiters_
Definition: TimedMutex.h:225
GuardImpl guard(ErrorHandler &&handler)
Definition: Base.h:840
auto ulock(Synchronized< D, M > &synchronized, Args &&...args)
template<typename BatonType >
bool folly::fibers::TimedRWMutex< BatonType >::try_read_lock ( )

Definition at line 209 of file TimedMutex-inl.h.

References folly::gen::guard(), and folly::fibers::TimedMutex::lock_.

209  {
210  std::lock_guard<SpinLock> guard{lock_};
211  if (state_ != State::WRITE_LOCKED) {
212  assert(
213  (state_ == State::UNLOCKED && readers_ == 0) ||
214  (state_ == State::READ_LOCKED && readers_ > 0));
215  assert(read_waiters_.empty());
217  readers_ += 1;
218  return true;
219  }
220  return false;
221 }
MutexWaiterList read_waiters_
Definition: TimedMutex.h:228
GuardImpl guard(ErrorHandler &&handler)
Definition: Base.h:840
template<typename BatonType >
bool folly::fibers::TimedRWMutex< BatonType >::try_write_lock ( )

Definition at line 268 of file TimedMutex-inl.h.

References folly::gen::guard(), and folly::fibers::TimedMutex::lock_.

268  {
269  std::lock_guard<SpinLock> guard{lock_};
270  if (state_ == State::UNLOCKED) {
273  return true;
274  }
275  return false;
276 }
GuardImpl guard(ErrorHandler &&handler)
Definition: Base.h:840
template<typename BatonType >
void folly::fibers::TimedRWMutex< BatonType >::unlock ( )

Definition at line 279 of file TimedMutex-inl.h.

References folly::fibers::TimedRWMutex< BatonType >::MutexWaiter::baton, folly::gen::guard(), and folly::fibers::TimedMutex::lock_.

279  {
280  std::lock_guard<SpinLock> guard{lock_};
281  assert(state_ != State::UNLOCKED);
282  assert(
283  (state_ == State::READ_LOCKED && readers_ > 0) ||
284  (state_ == State::WRITE_LOCKED && readers_ == 0));
285  if (state_ == State::READ_LOCKED) {
286  readers_ -= 1;
287  }
288 
289  if (!read_waiters_.empty()) {
290  assert(
291  state_ == State::WRITE_LOCKED && readers_ == 0 &&
292  "read waiters can only accumulate while write locked");
294  readers_ = read_waiters_.size();
295 
296  while (!read_waiters_.empty()) {
297  MutexWaiter& to_wake = read_waiters_.front();
298  read_waiters_.pop_front();
299  to_wake.baton.post();
300  }
301  } else if (readers_ == 0) {
302  if (!write_waiters_.empty()) {
303  assert(read_waiters_.empty());
305 
306  // Wake a single writer (after releasing the spin lock)
307  MutexWaiter& to_wake = write_waiters_.front();
308  write_waiters_.pop_front();
309  to_wake.baton.post();
310  } else {
312  state_ = State::UNLOCKED;
313  }
314  } else {
315  assert(state_ == State::READ_LOCKED);
316  }
317 }
MutexWaiterList read_waiters_
Definition: TimedMutex.h:228
MutexWaiterList write_waiters_
Definition: TimedMutex.h:225
GuardImpl guard(ErrorHandler &&handler)
Definition: Base.h:840
template<typename BatonType >
void folly::fibers::TimedRWMutex< BatonType >::verify_unlocked_properties ( )
inlineprivate

Definition at line 188 of file TimedMutex.h.

188  {
189  assert(readers_ == 0);
190  assert(read_waiters_.empty());
191  assert(write_waiters_.empty());
192  }
MutexWaiterList read_waiters_
Definition: TimedMutex.h:228
MutexWaiterList write_waiters_
Definition: TimedMutex.h:225
template<typename BatonType >
void folly::fibers::TimedRWMutex< BatonType >::write_lock ( )

Definition at line 224 of file TimedMutex-inl.h.

References folly::fibers::TimedRWMutex< BatonType >::MutexWaiter::baton, folly::fibers::TimedMutex::lock_, and folly::ulock().

224  {
225  std::unique_lock<folly::SpinLock> ulock{lock_};
226  if (state_ == State::UNLOCKED) {
229  return;
230  }
231  MutexWaiter waiter;
232  write_waiters_.push_back(waiter);
233  ulock.unlock();
234  waiter.baton.wait();
235 }
MutexWaiterList write_waiters_
Definition: TimedMutex.h:225
auto ulock(Synchronized< D, M > &synchronized, Args &&...args)

Member Data Documentation

template<typename BatonType >
folly::SpinLock folly::fibers::TimedRWMutex< BatonType >::lock_
private

Definition at line 219 of file TimedMutex.h.

template<typename BatonType >
MutexWaiterList folly::fibers::TimedRWMutex< BatonType >::read_waiters_
private

Definition at line 228 of file TimedMutex.h.

template<typename BatonType >
uint32_t folly::fibers::TimedRWMutex< BatonType >::readers_ = 0
private

Definition at line 223 of file TimedMutex.h.

template<typename BatonType >
State folly::fibers::TimedRWMutex< BatonType >::state_ = State::UNLOCKED
private

Definition at line 221 of file TimedMutex.h.

template<typename BatonType >
MutexWaiterList folly::fibers::TimedRWMutex< BatonType >::write_waiters_
private

Definition at line 225 of file TimedMutex.h.


The documentation for this class was generated from the following files: