@@ -16,6 +16,11 @@ namespace coro
16
16
namespace concepts
17
17
{
18
18
// clang-format off
19
+
20
+
21
+ /* *
22
+ * Concept of basic capabilities condition_variable
23
+ */
19
24
template <typename strategy_type>
20
25
concept cv_strategy_base = requires(strategy_type s)
21
26
{
@@ -24,6 +29,9 @@ concept cv_strategy_base = requires(strategy_type s)
24
29
{ s.wait_for_notify () } -> coro::concepts::awaiter;
25
30
};
26
31
32
+ /* *
33
+ * Concept of full capabilities condition_variable
34
+ */
27
35
template <typename strategy_type>
28
36
concept cv_strategy = cv_strategy_base<strategy_type> and requires (strategy_type s, coro::scoped_lock l, std::chrono::milliseconds d)
29
37
{
@@ -35,12 +43,16 @@ concept cv_strategy = cv_strategy_base<strategy_type> and requires(strategy_type
35
43
namespace detail
36
44
{
37
45
46
+ /* *
47
+ * The strategy implementing basic features of condition_variable, such as wait(), notify_one(), notify_all(). Does not
48
+ * require LIBCORO_FEATURE_NETWORKING for its operation
49
+ */
38
50
class strategy_base
39
51
{
40
52
public:
41
53
struct wait_operation
42
54
{
43
- explicit wait_operation (strategy_base& cv );
55
+ explicit wait_operation (strategy_base& strategy );
44
56
45
57
auto await_ready () const noexcept -> bool { return false ; }
46
58
auto await_suspend (std::coroutine_handle<> awaiting_coroutine) noexcept -> bool;
@@ -54,14 +66,18 @@ class strategy_base
54
66
std::atomic<wait_operation*> m_next{nullptr };
55
67
};
56
68
69
+ /* *
70
+ * Notifies and resumes one waiter immediately at the moment of the call, the calling coroutine will be forced to
71
+ * wait for the switching of the awakened coroutine
72
+ */
57
73
void notify_one () noexcept ;
58
74
59
75
/* *
60
76
* Notifies and resume one awaiters onto the given executor. This will distribute
61
77
* the waiters across the executor's threads.
62
78
*/
63
79
template <concepts::executor executor_type>
64
- [[nodiscard]] auto notify_one (executor_type& e) -> task<void>
80
+ void notify_one (executor_type& e)
65
81
{
66
82
while (true )
67
83
{
@@ -81,18 +97,20 @@ class strategy_base
81
97
e.resume (current->m_awaiting_coroutine );
82
98
break ;
83
99
}
84
-
85
- co_return ;
86
100
}
87
101
102
+ /* *
103
+ * Notifies and resumes all awaiters immediately at the moment of the call, the calling coroutine will be forced to
104
+ * wait for the switching of all awakened coroutines
105
+ */
88
106
void notify_all () noexcept ;
89
107
90
108
/* *
91
109
* Notifies and resumes all awaiters onto the given executor. This will distribute
92
110
* the waiters across the executor's threads.
93
111
*/
94
112
template <concepts::executor executor_type>
95
- [[nodiscard]] auto notify_all (executor_type& e) -> task<void>
113
+ void notify_all (executor_type& e)
96
114
{
97
115
while (true )
98
116
{
@@ -132,8 +150,6 @@ class strategy_base
132
150
e.resume (current->m_awaiting_coroutine );
133
151
} while (next);
134
152
}
135
-
136
- co_return ;
137
153
}
138
154
139
155
// / Internal helper function to wait for a condition variable
@@ -150,6 +166,10 @@ class strategy_base
150
166
151
167
#ifdef LIBCORO_FEATURE_NETWORKING
152
168
169
+ /* *
170
+ * The strategy fully implements all the capabilities of condition_variable, including such as wait_for(), wait_until().
171
+ * Requires LIBCORO_FEATURE_NETWORKING for its operation.
172
+ */
153
173
class strategy_based_on_io_scheduler
154
174
{
155
175
public:
@@ -158,7 +178,7 @@ class strategy_based_on_io_scheduler
158
178
159
179
struct wait_operation
160
180
{
161
- explicit wait_operation (strategy_based_on_io_scheduler& cv );
181
+ explicit wait_operation (strategy_based_on_io_scheduler& strategy );
162
182
~wait_operation ();
163
183
164
184
auto await_ready () const noexcept -> bool { return false ; }
@@ -234,18 +254,26 @@ class strategy_based_on_io_scheduler
234
254
// / a task with a time limit
235
255
[[nodiscard]] auto wait_task () -> task<bool>;
236
256
};
257
+ #endif
237
258
238
- using default_strategy = strategy_based_on_io_scheduler;
259
+ /* *
260
+ * You can set a custom default strategy for the coro::condition_variable
261
+ */
262
+ #ifdef LIBCORO_CONDITION_VARIABLE_DEFAULT_STRATEGY
263
+ using default_strategy = LIBCORO_CONDITION_VARIABLE_DEFAULT_STRATEGY;
239
264
#else
265
+ #ifdef LIBCORO_FEATURE_NETWORKING
266
+ using default_strategy = strategy_based_on_io_scheduler;
267
+ #else // LIBCORO_FEATURE_NETWORKING
240
268
using default_strategy = strategy_base;
241
- #endif
242
-
269
+ #endif // LIBCORO_FEATURE_NETWORKING
270
+ # endif // LIBCORO_CONDITION_VARIABLE_DEFAULT_STRATEGY
243
271
} // namespace detail
244
272
245
273
/* *
246
- * The coro::condition_variable is a thread safe async tool used with a coro::mutex (coro::scoped_lock)
274
+ * The coro::condition_variable_base is a thread safe async tool used with a coro::mutex (coro::scoped_lock)
247
275
* to suspend one or more coro::task until another coro::task both modifies a shared variable
248
- * (the condition) and notifies the coro::condition_variable
276
+ * (the condition) and notifies the coro::condition_variable_base
249
277
*/
250
278
template <concepts::cv_strategy_base Strategy>
251
279
class condition_variable_base : public Strategy
@@ -434,6 +462,9 @@ inline auto condition_variable_base<Strategy>::wait_for(
434
462
}
435
463
}
436
464
465
+ /* *
466
+ * this is coro::condition_variable_base with default strategy parameter (coro::detail::default_strategy)
467
+ */
437
468
using condition_variable = condition_variable_base<detail::default_strategy>;
438
469
439
470
} // namespace coro
0 commit comments