dispenso/rw_lock.h (15 lines of code) (raw):
// Copyright (c) Facebook, Inc. and its affiliates.
//
// This source code is licensed under the MIT license found in the
// LICENSE.md file in the root directory of this source tree.
#include <dispenso/detail/rw_lock_impl.h>
namespace dispenso {
/**
* A reader/writer lock interface compatible with std::shared_mutex (for use with std::unique_lock
* and std::shared_lock). The interface is designed to be very fast in the face of high levels of
* contention for high read traffic and low write traffic.
*
* @note RWLock is not as fully-featured as std::shared_mutex: It does not go to the OS to wait.
* This behavior is good for guarding very fast operations, but less good for guarding very slow
* operations. Additionally, RWLock is not compatible with std::condition_variable, though
* std::condition_variable_any may work (untested). It could be possible to extend RWLock with it's
* own ConditionVariable, make waiting operations sleep in the OS, and also to add timed functions;
* however those may slow things down in the fast case. If some/all of that functionality is
* needed, use std::shared_mutex, or develop a new type.
**/
class alignas(kCacheLineSize) RWLock : public detail::RWLockImpl {
public:
/**
* Locks for write access
*
* @note It is undefined behavior to recursively lock
**/
using detail::RWLockImpl::lock;
/**
* Tries to lock for write access, returns if unable to lock
*
* @return true if lock was acquired, false otherwise
**/
using detail::RWLockImpl::try_lock;
/**
* Unlocks write access
*
* @note Must already be locked by the current thread of execution, otherwise, the behavior is
* undefined.
**/
using detail::RWLockImpl::unlock;
/**
* Locks for read access
*
* @note It is undefined behavior to recursively lock
**/
using detail::RWLockImpl::lock_shared;
/**
* Tries to lock for read access, returns if unable to lock
*
* @return true if lock was acquired, false otherwise
*
* @note It is undefined behavior to recursively lock
**/
using detail::RWLockImpl::try_lock_shared;
/**
* Unlocks read access
*
* @note Must already be locked by the current thread of execution, otherwise, the behavior is
* undefined.
**/
using detail::RWLockImpl::unlock_shared;
/**
* Upgrade from a reader lock to a writer lock. lock_upgrade is a power-user interface. There is
* a very good reason why it is not exposed as upgrade_mutex in the standard. To use it safely,
* you *MUST* ensure only one thread can try to lock for write concurrently. If that cannot be
* guaranteed, you should unlock for read, and lock for write instead of using lock_upgrade to
* avoid potential deadlock.
*
* @note Calling this if the writer lock is already held, or if no reader lock is already held is
* undefined behavior.
**/
using detail::RWLockImpl::lock_upgrade;
/**
* Downgrade the lock from a writer lock to a reader lock.
*
* @note Calling this if the writer lock is not held results in undefined behavior
**/
using detail::RWLockImpl::lock_downgrade;
};
/**
* An unaligned version of the RWLock. This could be useful if you e.g. want to create an array of
* these to guard a large number of slots, and the likelihood of multiple threads touching any
* region concurrently is low. All other behavior remains the same, so refer to the documentation
* for RWLock.
**/
class UnalignedRWLock : public detail::RWLockImpl {};
} // namespace dispenso