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 {
29public:
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 task if the mutex is locked by
39 /// another task. Throws if a task tries to lock a mutex
40 /// which is already locked by the current task.
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 by the current task.
47 ///
48 /// @note the order of tasks to unblock is unspecified. Any code assuming
49 /// any specific order (e.g. FIFO) is incorrect and should be fixed.
50 void unlock();
51
52 /// Tries to lock the mutex without blocking the task, returns true if succeeded.
53 ///
54 /// @note The behavior of the function is not affected by the cancellation
55 /// requests.
56 [[nodiscard]] bool try_lock() noexcept;
57
58 /// Tries to lock the mutex in specified duration. Blocks current task if
59 /// the mutex is locked by another task up to the provided duration.
60 /// Throws if a task tries to lock a mutex which is already locked by the current task.
61 ///
62 /// @returns true if the locking succeeded
63 ///
64 /// @note The method waits for the mutex even if the current task is
65 /// cancelled.
66 template <typename Rep, typename Period>
67 [[nodiscard]] bool try_lock_for(const std::chrono::duration<Rep, Period>&);
68
69 /// Tries to lock the mutex till specified time point. Blocks current
70 /// task if the mutex is locked by another task up to the provided
71 /// time point. Throws if a task tries to lock a mutex which is already locked by the current task.
72 ///
73 /// @returns true if the locking succeeded
74 ///
75 /// @note The method waits for the mutex even if the current task is
76 /// cancelled.
77 template <typename Clock, typename Duration>
78 [[nodiscard]] bool try_lock_until(const std::chrono::time_point<Clock, Duration>&);
79
80 /// @overload
81 [[nodiscard]] bool try_lock_until(Deadline deadline);
82
83private:
84 class Impl;
85
86 utils::FastPimpl<Impl, 96, alignof(void*)> impl_;
87};
88
89template <typename Rep, typename Period>
90bool Mutex::try_lock_for(const std::chrono::duration<Rep, Period>& duration) {
91 return try_lock_until(Deadline::FromDuration(duration));
92}
93
94template <typename Clock, typename Duration>
95bool Mutex::try_lock_until(const std::chrono::time_point<Clock, Duration>& until) {
96 return try_lock_until(Deadline::FromTimePoint(until));
97}
98
99} // namespace engine
100
101USERVER_NAMESPACE_END