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/// ## Example usage:
26///
27/// The class's API is the same as of engine::Mutex:
28///
29/// @snippet engine/mutex_test.cpp Sample engine::Mutex usage
30///
31/// @see @ref scripts/docs/en/userver/synchronization.md
32class SingleWaitingTaskMutex final {
33 public:
34 SingleWaitingTaskMutex();
35 ~SingleWaitingTaskMutex();
36
37 SingleWaitingTaskMutex(const SingleWaitingTaskMutex&) = delete;
38 SingleWaitingTaskMutex(SingleWaitingTaskMutex&&) = delete;
39 SingleWaitingTaskMutex& operator=(const SingleWaitingTaskMutex&) = delete;
40 SingleWaitingTaskMutex& operator=(SingleWaitingTaskMutex&&) = delete;
41
42 /// Locks the mutex. Blocks current coroutine if the mutex is locked by
43 /// another coroutine.
44 /// @note the behaviour is undefined if a coroutine tries to lock a mutex
45 /// which is already locked by the current coroutine.
46 /// @note the method waits for the mutex even if the current task is
47 /// cancelled.
48 void lock();
49
50 /// Unlocks the mutex. The mutex must be locked by the current coroutine.
51 /// @note the behaviour is undefined if a coroutine tries to unlock a mutex
52 /// which is not locked or is locked by another coroutine
53 void unlock();
54
55 bool try_lock();
56
57 template <typename Rep, typename Period>
58 bool try_lock_for(const std::chrono::duration<Rep, Period>&);
59
60 template <typename Clock, typename Duration>
61 bool try_lock_until(const std::chrono::time_point<Clock, Duration>&);
62
63 bool try_lock_until(Deadline deadline);
64
65 private:
66 class Impl;
67
68 utils::FastPimpl<Impl, 32, 16> impl_;
69};
70
71template <typename Rep, typename Period>
72bool SingleWaitingTaskMutex::try_lock_for(
73 const std::chrono::duration<Rep, Period>& duration) {
74 return try_lock_until(Deadline::FromDuration(duration));
75}
76
77template <typename Clock, typename Duration>
78bool SingleWaitingTaskMutex::try_lock_until(
79 const std::chrono::time_point<Clock, Duration>& until) {
80 return try_lock_until(Deadline::FromTimePoint(until));
81}
82
83} // namespace engine
84
85USERVER_NAMESPACE_END