userver: userver/engine/mutex.hpp Source File
Loading...
Searching...
No Matches
mutex.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/engine/mutex.hpp
4/// @brief @copybrief engine::Mutex
5
6#include <atomic>
7#include <chrono>
8#include <mutex> // for std locks
9
10#include <userver/engine/deadline.hpp>
11#include <userver/engine/impl/wait_list_fwd.hpp>
12
13USERVER_NAMESPACE_BEGIN
14
15namespace engine {
16
17/// @ingroup userver_concurrency
18///
19/// @brief std::mutex replacement for asynchronous tasks.
20///
21/// Ignores task cancellations (succeeds even if the current task is cancelled).
22///
23/// ## Example usage:
24///
25/// @snippet engine/mutex_test.cpp Sample engine::Mutex usage
26///
27/// @see @ref scripts/docs/en/userver/synchronization.md
28class Mutex final {
29 public:
30 Mutex();
31 ~Mutex();
32
33 Mutex(const Mutex&) = delete;
34 Mutex(Mutex&&) = delete;
35 Mutex& operator=(const Mutex&) = delete;
36 Mutex& operator=(Mutex&&) = delete;
37
38 /// Locks the mutex. Blocks current coroutine if the mutex is locked by
39 /// another coroutine. Throws if a coroutine tries to lock a mutex
40 /// which is already locked by the current coroutine.
41 ///
42 /// @note The method waits for the mutex even if the current task is
43 /// cancelled.
44 void lock();
45
46 /// Unlocks the mutex. Before calling this method the mutex should be locked
47 /// by the current coroutine.
48 ///
49 /// @note the order of coroutines to unblock is unspecified. Any code assuming
50 /// any specific order (e.g. FIFO) is incorrect and should be fixed.
51 void unlock();
52
53 /// Tries to lock the mutex without blocking the coroutine, returns true if
54 /// succeeded.
55 ///
56 /// @note The behavior of the function is not affected by cancelation request.
57 [[nodiscard]] bool try_lock() noexcept;
58
59 /// Tries to lock the mutex in specified duration. Blocks current coroutine if
60 /// the mutex is locked by another coroutine up to the provided duration.
61 /// Throws if a coroutine tries to lock a mutex
62 /// which is already locked by the current coroutine.
63 ///
64 /// @returns true if the locking succeeded
65 ///
66 /// @note The method waits for the mutex even if the current task is
67 /// cancelled.
68 template <typename Rep, typename Period>
69 [[nodiscard]] bool try_lock_for(const std::chrono::duration<Rep, Period>&);
70
71 /// Tries to lock the mutex till specified time point. Blocks current
72 /// coroutine if the mutex is locked by another coroutine up to the provided
73 /// time point. Throws if a coroutine tries to lock a mutex
74 /// which is already locked by the current coroutine.
75 ///
76 /// @returns true if the locking succeeded
77 ///
78 /// @note The method waits for the mutex even if the current task is
79 /// cancelled.
80 template <typename Clock, typename Duration>
81 [[nodiscard]] bool try_lock_until(
82 const std::chrono::time_point<Clock, Duration>&);
83
84 /// @overload
85 [[nodiscard]] bool try_lock_until(Deadline deadline);
86
87 private:
88 class Impl;
89
90 utils::FastPimpl<Impl, 96, alignof(void*)> impl_;
91};
92
93template <typename Rep, typename Period>
94bool Mutex::try_lock_for(const std::chrono::duration<Rep, Period>& duration) {
95 return try_lock_until(Deadline::FromDuration(duration));
96}
97
98template <typename Clock, typename Duration>
99bool Mutex::try_lock_until(
100 const std::chrono::time_point<Clock, Duration>& until) {
101 return try_lock_until(Deadline::FromTimePoint(until));
102}
103
104} // namespace engine
105
106USERVER_NAMESPACE_END