]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/third-party/folly/folly/synchronization/detail/ProxyLockable.h
1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under both the GPLv2 (found in the
3 // COPYING file in the root directory) and Apache 2.0 License
4 // (found in the LICENSE.Apache file in the root directory).
8 #include <folly/Optional.h>
16 * ProxyLockable is a "concept" that is used usually for mutexes that don't
17 * return void, but rather a proxy object that contains data that should be
18 * passed to the unlock function.
20 * This is in contrast with the normal Lockable concept that imposes no
21 * requirement on the return type of lock(), and requires an unlock() with no
22 * parameters. Here we require that lock() returns non-void and that unlock()
23 * accepts the return type of lock() by value, rvalue-reference or
26 * Here we define two classes, that can be used by the top level to implement
27 * specializations for std::unique_lock and std::lock_guard. Both
28 * ProxyLockableUniqueLock and ProxyLockableLockGuard implement the entire
29 * interface of std::unique_lock and std::lock_guard respectively
31 template <typename Mutex
>
32 class ProxyLockableUniqueLock
{
34 using mutex_type
= Mutex
;
36 _t
<std::decay
<decltype(std::declval
<mutex_type
>().lock())>>;
39 * Default constructor initializes the unique_lock to an empty state
41 ProxyLockableUniqueLock() = default;
44 * Destructor releases the mutex if it is locked
46 ~ProxyLockableUniqueLock();
49 * Move constructor and move assignment operators take state from the other
52 ProxyLockableUniqueLock(ProxyLockableUniqueLock
&& other
) noexcept
;
53 ProxyLockableUniqueLock
& operator=(ProxyLockableUniqueLock
&&) noexcept
;
56 * Locks the mutex, blocks until the mutex can be acquired.
58 * The mutex is guaranteed to be acquired after this function returns.
60 ProxyLockableUniqueLock(mutex_type
&) noexcept
;
63 * Explicit locking constructors to control how the lock() method is called
65 * std::defer_lock_t causes the mutex to get tracked, but not locked
66 * std::try_to_lock_t causes try_lock() to be called. The current object is
67 * converts to true if the lock was successful
69 ProxyLockableUniqueLock(mutex_type
& mtx
, std::defer_lock_t
) noexcept
;
70 ProxyLockableUniqueLock(mutex_type
& mtx
, std::try_to_lock_t
);
73 * Timed locking constructors
75 template <typename Rep
, typename Period
>
76 ProxyLockableUniqueLock(
78 const std::chrono::duration
<Rep
, Period
>& duration
);
79 template <typename Clock
, typename Duration
>
80 ProxyLockableUniqueLock(
82 const std::chrono::time_point
<Clock
, Duration
>& time
);
85 * Lock and unlock methods
87 * lock() and try_lock() throw if the mutex is already locked, or there is
88 * no mutex. unlock() throws if there is no mutex or if the mutex was not
96 * Timed locking methods
98 * These throw if there was no mutex, or if the mutex was already locked
100 template <typename Rep
, typename Period
>
101 bool try_lock_for(const std::chrono::duration
<Rep
, Period
>& duration
);
102 template <typename Clock
, typename Duration
>
103 bool try_lock_until(const std::chrono::time_point
<Clock
, Duration
>& time
);
106 * Swap this unique lock with the other one
108 void swap(ProxyLockableUniqueLock
& other
) noexcept
;
111 * Returns true if the unique lock contains a lock and also has acquired an
112 * exclusive lock successfully
114 bool owns_lock() const noexcept
;
115 explicit operator bool() const noexcept
;
118 * mutex() return a pointer to the mutex if there is a contained mutex and
119 * proxy() returns a pointer to the contained proxy if the mutex is locked
121 * If the unique lock was not constructed with a mutex, then mutex() returns
122 * nullptr. If the mutex is not locked, then proxy() returns nullptr
124 mutex_type
* mutex() const noexcept
;
125 proxy_type
* proxy() const noexcept
;
128 friend class ProxyLockableTest
;
131 * If the optional has a value, the mutex is locked, if it is empty, it is
134 mutable folly::Optional
<proxy_type
> proxy_
{};
135 mutex_type
* mutex_
{nullptr};
138 template <typename Mutex
>
139 class ProxyLockableLockGuard
: private ProxyLockableUniqueLock
<Mutex
> {
141 using mutex_type
= Mutex
;
144 * Constructor locks the mutex, and destructor unlocks
146 ProxyLockableLockGuard(mutex_type
& mtx
);
147 ~ProxyLockableLockGuard() = default;
150 * This class is not movable or assignable
152 * For more complicated usecases, consider the UniqueLock variant, which
153 * provides more options
155 ProxyLockableLockGuard(const ProxyLockableLockGuard
&) = delete;
156 ProxyLockableLockGuard(ProxyLockableLockGuard
&&) = delete;
157 ProxyLockableLockGuard
& operator=(ProxyLockableLockGuard
&&) = delete;
158 ProxyLockableLockGuard
& operator=(const ProxyLockableLockGuard
&) = delete;
161 } // namespace detail
164 #include <folly/synchronization/detail/ProxyLockable-inl.h>