LeechCraft
0.6.70-19214-g121e5318a7
Modular cross-platform feature rich live environment.
Toggle main menu visibility
Loading...
Searching...
No Matches
task.h
Go to the documentation of this file.
1
/**********************************************************************
2
* LeechCraft - modular cross-platform feature rich internet client.
3
* Copyright (C) 2006-2014 Georg Rudoy
4
*
5
* Distributed under the Boost Software License, Version 1.0.
6
* (See accompanying file LICENSE or copy at https://www.boost.org/LICENSE_1_0.txt)
7
**********************************************************************/
8
9
#pragma once
10
11
#include <coroutine>
12
#include <exception>
13
#include <mutex>
14
#include <utility>
15
#include "
finalsuspender.h
"
16
#include "
defaulthandlers.h
"
17
#include "
taskfwd.h
"
18
19
namespace
LC::Util
20
{
21
namespace
detail
22
{
23
struct
PromiseBase
24
{
25
std::atomic<size_t>
Refs_
= 1;
26
std::exception_ptr
Exception_
{};
27
28
enum class
CoroState
: std::uint8_t
29
{
30
Running
,
31
Suspended,
32
Finished
,
33
};
34
CoroState
State_
=
CoroState::Running
;
35
};
36
37
template
<
typename
R>
38
struct
PromiseRet
:
PromiseBase
39
{
40
using
ReturnType_t
= R;
41
42
constexpr
static
bool
IsVoid
=
false
;
43
44
std::optional<R>
Ret_
;
45
46
template
<
typename
U = R>
47
void
return_value
(
this
auto
&& self, U&& val)
48
{
49
std::lock_guard guard { self };
50
self.Ret_.emplace (std::forward<U> (val));
51
}
52
};
53
54
template
<>
55
struct
PromiseRet
<void> :
PromiseBase
56
{
57
constexpr
static
bool
IsVoid
=
true
;
58
59
bool
Done_
=
false
;
60
61
void
return_void
(
this
auto
&& self)
noexcept
62
{
63
std::lock_guard guard { self };
64
self.Done_ =
true
;
65
}
66
};
67
68
struct
EitherFailureAbort
final : std::exception {};
69
70
template
<
typename
Promise>
71
struct
TaskAwaiter
72
{
73
using
Handle_t
= std::coroutine_handle<Promise>;
74
Handle_t
Subtask_
;
75
76
std::coroutine_handle<>
OuterTask_
;
77
78
explicit
TaskAwaiter
(
Handle_t
subtask)
79
:
Subtask_
{ subtask }
80
{
81
if
(
Subtask_
)
82
Subtask_
.promise ().IncRef ();
83
}
84
85
TaskAwaiter
(
TaskAwaiter
&& other) noexcept
86
:
Subtask_
{ std::exchange (other.Subtask_, {}) }
87
,
OuterTask_
{ std::exchange (other.OuterTask_, {}) }
88
{
89
}
90
91
TaskAwaiter
(
const
TaskAwaiter
&) =
delete
;
92
TaskAwaiter
&
operator=
(
const
TaskAwaiter
&) =
delete
;
93
TaskAwaiter
&
operator=
(
TaskAwaiter
&& other) =
delete
;
94
95
~TaskAwaiter
()
96
{
97
if
(
Subtask_
&&
OuterTask_
)
98
{
99
auto
& promise =
Subtask_
.promise ();
100
std::lock_guard guard { promise };
101
promise.RemoveAwaiter (
OuterTask_
);
102
}
103
104
if
(
Subtask_
)
105
Subtask_
.promise ().DecRef ();
106
}
107
108
bool
await_ready
() const noexcept
109
{
110
const
auto
& promise =
Subtask_
.promise ();
111
std::lock_guard guard { promise };
112
return
CheckTaskFinishedUnlocked (promise);
113
}
114
115
bool
await_suspend
(std::coroutine_handle<> handle)
116
{
117
auto
& promise =
Subtask_
.promise ();
118
std::lock_guard guard { promise };
119
if
(CheckTaskFinishedUnlocked (promise))
120
return
false
;
121
122
OuterTask_
= handle;
123
promise.AddAwaiter (handle);
124
return
true
;
125
}
126
127
auto
await_resume
()
128
{
129
auto
& promise =
Subtask_
.promise ();
130
std::lock_guard guard { promise };
131
if
(promise.Exception_)
132
try
133
{
134
std::rethrow_exception (promise.Exception_);
135
}
136
catch
(
const
EitherFailureAbort
&)
137
{
138
}
139
140
if
constexpr
(!Promise::IsVoid)
141
return
Promise::ResumeValue (*promise.Ret_);
142
}
143
private
:
144
bool
CheckTaskFinishedUnlocked (
const
Promise& promise)
const
145
{
146
if
(promise.Exception_)
147
return
true
;
148
149
if
constexpr
(Promise::IsVoid)
150
return
promise.Done_;
151
else
152
return
static_cast<
bool
>
(promise.Ret_);
153
}
154
};
155
}
156
157
template
<
typename
R,
template
<
typename
>
typename
... Extensions>
158
class
Task
159
{
160
public
:
161
struct
promise_type
;
162
private
:
163
using
Handle_t = std::coroutine_handle<promise_type>;
164
Handle_t Handle_;
165
public
:
166
struct
promise_type
167
:
detail::PromiseRet
<R>
168
, Extensions<promise_type>...
169
,
detail::DefaultAwaiterHandler
<Extensions<promise_type>...>
170
,
detail::DefaultLockingHandler
<Extensions<promise_type>...>
171
,
detail::DefaultResumeValueHandler
<Extensions<promise_type>...>
172
{
173
auto
GetAddress
() {
return
Handle_t::from_promise (*this).address (); }
174
175
Task
get_return_object
()
176
{
177
return
Task
{ Handle_t::from_promise (*
this
) };
178
}
179
180
std::suspend_never
initial_suspend
() const noexcept {
return
{}; }
181
182
auto
final_suspend
() noexcept
183
{
184
this->
State_
=
detail::PromiseBase::CoroState::Finished
;
185
return
detail::FinalSuspender<promise_type>
{ *
this
};
186
}
187
188
void
unhandled_exception
()
189
{
190
this->
Exception_
= std::current_exception ();
191
}
192
193
void
IncRef
()
194
{
195
this->
Refs_
.fetch_add (1);
196
}
197
198
void
DecRef
()
199
{
200
if
(this->
Refs_
.fetch_sub (1) == 1)
201
Handle_t::from_promise (*this).destroy ();
202
}
203
};
204
205
using
ResultType_t
= R;
206
207
template
<
typename
RR>
208
using
ReplaceResult_t
=
Task
<RR, Extensions...>;
209
210
template
<
template
<
typename
>
typename
F>
211
using
ApplyResult_t
=
Task<F<R>
, Extensions...>;
212
213
explicit
Task
(
const
std::coroutine_handle<promise_type>& handle)
214
: Handle_ { handle }
215
{
216
if
(handle)
217
handle.promise ().IncRef ();
218
}
219
220
~Task
() noexcept
221
{
222
if
(Handle_)
223
Handle_.promise ().DecRef ();
224
}
225
226
Task
(
const
Task
& other)
227
: Handle_ { other.Handle_ }
228
{
229
if
(Handle_)
230
Handle_.promise ().IncRef ();
231
}
232
233
Task
&
operator=
(
const
Task
& other)
234
{
235
Task
task { other };
236
*
this
= std::move (task);
237
return
*
this
;
238
}
239
240
Task
(
Task
&& other)
noexcept
241
{
242
std::swap (Handle_, other.Handle_);
243
}
244
245
Task
&
operator=
(
Task
&& other)
noexcept
246
{
247
std::swap (Handle_, other.Handle_);
248
return
*
this
;
249
}
250
251
auto
operator
co_await
()
const
noexcept
252
{
253
return
detail::TaskAwaiter<promise_type>
{ Handle_ };
254
}
255
};
256
257
namespace
detail
258
{
259
template
<
typename
R,
template
<
typename
>
typename
... Extensions>
260
struct
GetPromise
261
{
262
using
Promise
=
typename
Task
<R, Extensions...>::promise_type;
263
Promise
*
Promise_
=
nullptr
;
264
265
bool
await_ready
() const noexcept {
return
false
; }
266
267
bool
await_suspend
(std::coroutine_handle<Promise> handle)
noexcept
268
{
269
Promise_
= &handle.promise ();
270
return
false
;
271
}
272
273
decltype
(
auto
)
await_resume
()
const
noexcept
274
{
275
return
*
Promise_
;
276
}
277
};
278
}
279
}
LC::Util::Task
Definition
task.h:159
LC::Util::Task< T, SharedTaskExtension >::ResultType_t
T ResultType_t
Definition
task.h:205
LC::Util::Task::operator=
Task & operator=(const Task &other)
Definition
task.h:233
LC::Util::Task::Task
Task(Task &&other) noexcept
Definition
task.h:240
LC::Util::Task::~Task
~Task() noexcept
Definition
task.h:220
LC::Util::Task< T, SharedTaskExtension >::ApplyResult_t
Task< F< T >, SharedTaskExtension... > ApplyResult_t
Definition
task.h:211
LC::Util::Task< T, SharedTaskExtension >::ReplaceResult_t
Task< RR, SharedTaskExtension... > ReplaceResult_t
Definition
task.h:208
LC::Util::Task::Task
Task(const Task &other)
Definition
task.h:226
LC::Util::Task::Task
Task(const std::coroutine_handle< promise_type > &handle)
Definition
task.h:213
defaulthandlers.h
finalsuspender.h
LC::Util::detail
Definition
fancytrayiconfreedesktop.cpp:24
LC::Util
Definition
icoreproxy.h:34
LC::ProcessState::Running
@ Running
Definition
ijobholder.h:77
LC::ProcessState::Finished
@ Finished
Definition
ijobholder.h:79
LC::Util::Task::promise_type
Definition
task.h:172
LC::Util::Task::promise_type::initial_suspend
std::suspend_never initial_suspend() const noexcept
Definition
task.h:180
LC::Util::Task::promise_type::GetAddress
auto GetAddress()
Definition
task.h:173
LC::Util::Task::promise_type::IncRef
void IncRef()
Definition
task.h:193
LC::Util::Task::promise_type::final_suspend
auto final_suspend() noexcept
Definition
task.h:182
LC::Util::Task::promise_type::DecRef
void DecRef()
Definition
task.h:198
LC::Util::Task::promise_type::unhandled_exception
void unhandled_exception()
Definition
task.h:188
LC::Util::Task::promise_type::get_return_object
Task get_return_object()
Definition
task.h:175
LC::Util::detail::DefaultAwaiterHandler
Definition
defaulthandlers.h:22
LC::Util::detail::DefaultLockingHandler
Definition
defaulthandlers.h:60
LC::Util::detail::DefaultResumeValueHandler
Definition
defaulthandlers.h:75
LC::Util::detail::EitherFailureAbort
Definition
task.h:68
LC::Util::detail::FinalSuspender
Definition
finalsuspender.h:18
LC::Util::detail::GetPromise
Definition
task.h:261
LC::Util::detail::GetPromise::await_ready
bool await_ready() const noexcept
Definition
task.h:265
LC::Util::detail::GetPromise::await_resume
decltype(auto) await_resume() const noexcept
Definition
task.h:273
LC::Util::detail::GetPromise::await_suspend
bool await_suspend(std::coroutine_handle< Promise > handle) noexcept
Definition
task.h:267
LC::Util::detail::GetPromise::Promise
typename Task< R, Extensions... >::promise_type Promise
Definition
task.h:262
LC::Util::detail::GetPromise::Promise_
Promise * Promise_
Definition
task.h:263
LC::Util::detail::PromiseBase
Definition
task.h:24
LC::Util::detail::PromiseBase::Exception_
std::exception_ptr Exception_
Definition
task.h:26
LC::Util::detail::PromiseBase::Refs_
std::atomic< size_t > Refs_
Definition
task.h:25
LC::Util::detail::PromiseBase::State_
CoroState State_
Definition
task.h:34
LC::Util::detail::PromiseBase::CoroState
CoroState
Definition
task.h:29
LC::Util::detail::PromiseBase::CoroState::Running
@ Running
Definition
task.h:30
LC::Util::detail::PromiseBase::CoroState::Finished
@ Finished
Definition
task.h:32
LC::Util::detail::PromiseRet< void >::IsVoid
static constexpr bool IsVoid
Definition
task.h:57
LC::Util::detail::PromiseRet< void >::Done_
bool Done_
Definition
task.h:59
LC::Util::detail::PromiseRet< void >::return_void
void return_void(this auto &&self) noexcept
Definition
task.h:61
LC::Util::detail::PromiseRet
Definition
task.h:39
LC::Util::detail::PromiseRet::Ret_
std::optional< R > Ret_
Definition
task.h:44
LC::Util::detail::PromiseRet::IsVoid
static constexpr bool IsVoid
Definition
task.h:42
LC::Util::detail::PromiseRet::ReturnType_t
R ReturnType_t
Definition
task.h:40
LC::Util::detail::PromiseRet::return_value
void return_value(this auto &&self, U &&val)
Definition
task.h:47
LC::Util::detail::TaskAwaiter
Definition
task.h:72
LC::Util::detail::TaskAwaiter::await_ready
bool await_ready() const noexcept
Definition
task.h:108
LC::Util::detail::TaskAwaiter::TaskAwaiter
TaskAwaiter(Handle_t subtask)
Definition
task.h:78
LC::Util::detail::TaskAwaiter::await_resume
auto await_resume()
Definition
task.h:127
LC::Util::detail::TaskAwaiter::Handle_t
std::coroutine_handle< Promise > Handle_t
Definition
task.h:73
LC::Util::detail::TaskAwaiter::operator=
TaskAwaiter & operator=(const TaskAwaiter &)=delete
LC::Util::detail::TaskAwaiter::Subtask_
Handle_t Subtask_
Definition
task.h:74
LC::Util::detail::TaskAwaiter::TaskAwaiter
TaskAwaiter(TaskAwaiter &&other) noexcept
Definition
task.h:85
LC::Util::detail::TaskAwaiter::await_suspend
bool await_suspend(std::coroutine_handle<> handle)
Definition
task.h:115
LC::Util::detail::TaskAwaiter::TaskAwaiter
TaskAwaiter(const TaskAwaiter &)=delete
LC::Util::detail::TaskAwaiter::OuterTask_
std::coroutine_handle OuterTask_
Definition
task.h:76
LC::Util::detail::TaskAwaiter::~TaskAwaiter
~TaskAwaiter()
Definition
task.h:95
taskfwd.h
src
util
threads
coro
task.h
Generated by
1.18.0