userver: userver/engine/mutex.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
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