userver: userver/engine/single_waiting_task_mutex.hpp Source File
Loading...
Searching...
No Matches
single_waiting_task_mutex.hpp
1#pragma once
2
3/// @file userver/engine/single_waiter_mutex.hpp
4/// @brief @copybrief engine::SingleWaitingTaskMutex
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 Lighter version of Mutex with not more than 1 waiting task.
20///
21/// There are some situations when a resource is accessed
22/// concurrently, but concurrency factor is limited by 2.
23/// For instance: implications of socket r/w duality.
24///
25/// Ignores task cancellations (succeeds even if the current task is cancelled).
26///
27/// ## Example usage:
28///
29/// The class's API is the same as of engine::Mutex:
30///
31/// @snippet engine/mutex_test.cpp Sample engine::Mutex usage
32///
33/// @see @ref scripts/docs/en/userver/synchronization.md
34class SingleWaitingTaskMutex final {
35 public:
36 SingleWaitingTaskMutex();
37 ~SingleWaitingTaskMutex();
38
39 SingleWaitingTaskMutex(const SingleWaitingTaskMutex&) = delete;
40 SingleWaitingTaskMutex(SingleWaitingTaskMutex&&) = delete;
41 SingleWaitingTaskMutex& operator=(const SingleWaitingTaskMutex&) = delete;
42 SingleWaitingTaskMutex& operator=(SingleWaitingTaskMutex&&) = delete;
43
44 /// Locks the mutex. Blocks current coroutine if the mutex is locked by
45 /// another coroutine.
46 /// @note the behaviour is undefined if a coroutine tries to lock a mutex
47 /// which is already locked by the current coroutine.
48 /// @note the method waits for the mutex even if the current task is
49 /// cancelled.
50 void lock();
51
52 /// Unlocks the mutex. Before calling this method the mutex should be locked
53 /// by the current coroutine.
54 void unlock();
55
56 bool try_lock();
57
58 template <typename Rep, typename Period>
59 bool try_lock_for(const std::chrono::duration<Rep, Period>&);
60
61 template <typename Clock, typename Duration>
62 bool try_lock_until(const std::chrono::time_point<Clock, Duration>&);
63
64 bool try_lock_until(Deadline deadline);
65
66 private:
67 class Impl;
68
69 utils::FastPimpl<Impl, 32, 16> impl_;
70};
71
72template <typename Rep, typename Period>
73bool SingleWaitingTaskMutex::try_lock_for(
74 const std::chrono::duration<Rep, Period>& duration) {
75 return try_lock_until(Deadline::FromDuration(duration));
76}
77
78template <typename Clock, typename Duration>
79bool SingleWaitingTaskMutex::try_lock_until(
80 const std::chrono::time_point<Clock, Duration>& until) {
81 return try_lock_until(Deadline::FromTimePoint(until));
82}
83
84} // namespace engine
85
86USERVER_NAMESPACE_END