LeechCraft
0.6.70-18808-g3467692359
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
29
template
<
typename
R>
30
struct
PromiseRet
:
PromiseBase
31
{
32
using
ReturnType_t
= R;
33
34
constexpr
static
bool
IsVoid
=
false
;
35
36
std::optional<R>
Ret_
;
37
38
template
<
typename
U = R>
39
void
return_value
(
this
auto
&& self, U&& val)
40
{
41
std::lock_guard guard { self };
42
self.Ret_.emplace (std::forward<U> (val));
43
}
44
};
45
46
template
<>
47
struct
PromiseRet
<void> :
PromiseBase
48
{
49
constexpr
static
bool
IsVoid
=
true
;
50
51
bool
Done_
=
false
;
52
53
void
return_void
(
this
auto
&& self)
noexcept
54
{
55
std::lock_guard guard { self };
56
self.Done_ =
true
;
57
}
58
};
59
60
struct
EitherFailureAbort
final : std::exception {};
61
62
template
<
typename
Promise>
63
struct
TaskAwaiter
64
{
65
using
Handle_t
= std::coroutine_handle<Promise>;
66
Handle_t
Subtask_
;
67
68
std::coroutine_handle<>
OuterTask_
;
69
70
explicit
TaskAwaiter
(
Handle_t
subtask)
71
:
Subtask_
{ subtask }
72
{
73
if
(
Subtask_
)
74
Subtask_
.promise ().IncRef ();
75
}
76
77
TaskAwaiter
(
TaskAwaiter
&& other) noexcept
78
:
Subtask_
{ std::exchange (other.Subtask_, {}) }
79
,
OuterTask_
{ std::exchange (other.OuterTask_, {}) }
80
{
81
}
82
83
TaskAwaiter
(
const
TaskAwaiter
&) =
delete
;
84
TaskAwaiter
&
operator=
(
const
TaskAwaiter
&) =
delete
;
85
TaskAwaiter
&
operator=
(
TaskAwaiter
&& other) =
delete
;
86
87
~TaskAwaiter
()
88
{
89
if
(
Subtask_
&&
OuterTask_
)
90
{
91
auto
& promise =
Subtask_
.promise ();
92
std::lock_guard guard { promise };
93
promise.RemoveAwaiter (
OuterTask_
);
94
}
95
96
if
(
Subtask_
)
97
Subtask_
.promise ().DecRef ();
98
}
99
100
bool
await_ready
() const noexcept
101
{
102
const
auto
& promise =
Subtask_
.promise ();
103
std::lock_guard guard { promise };
104
return
CheckTaskFinishedUnlocked (promise);
105
}
106
107
bool
await_suspend
(std::coroutine_handle<> handle)
108
{
109
auto
& promise =
Subtask_
.promise ();
110
std::lock_guard guard { promise };
111
if
(CheckTaskFinishedUnlocked (promise))
112
return
false
;
113
114
OuterTask_
= handle;
115
promise.AddAwaiter (handle);
116
return
true
;
117
}
118
119
auto
await_resume
()
120
{
121
auto
& promise =
Subtask_
.promise ();
122
std::lock_guard guard { promise };
123
if
(promise.Exception_)
124
try
125
{
126
std::rethrow_exception (promise.Exception_);
127
}
128
catch
(
const
EitherFailureAbort
&)
129
{
130
}
131
132
if
constexpr
(!Promise::IsVoid)
133
return
Promise::ResumeValue (*promise.Ret_);
134
}
135
private
:
136
bool
CheckTaskFinishedUnlocked (
const
Promise& promise)
const
137
{
138
if
(promise.Exception_)
139
return
true
;
140
141
if
constexpr
(Promise::IsVoid)
142
return
promise.Done_;
143
else
144
return
static_cast<
bool
>
(promise.Ret_);
145
}
146
};
147
}
148
149
template
<
typename
R,
template
<
typename
>
typename
... Extensions>
150
class
Task
151
{
152
public
:
153
struct
promise_type
;
154
private
:
155
using
Handle_t = std::coroutine_handle<promise_type>;
156
Handle_t Handle_;
157
public
:
158
struct
promise_type
159
:
detail::PromiseRet
<R>
160
, Extensions<promise_type>...
161
,
detail::DefaultAwaiterHandler
<Extensions<promise_type>...>
162
,
detail::DefaultLockingHandler
<Extensions<promise_type>...>
163
,
detail::DefaultResumeValueHandler
<Extensions<promise_type>...>
164
{
165
auto
GetAddress
() {
return
Handle_t::from_promise (*this).address (); }
166
167
Task
get_return_object
()
168
{
169
return
Task
{ Handle_t::from_promise (*
this
) };
170
}
171
172
std::suspend_never
initial_suspend
() const noexcept {
return
{}; }
173
174
auto
final_suspend
() noexcept {
return
detail::FinalSuspender<promise_type>
{ *
this
}; }
175
176
void
unhandled_exception
()
177
{
178
this->
Exception_
= std::current_exception ();
179
}
180
181
void
IncRef
()
182
{
183
this->
Refs_
.fetch_add (1);
184
}
185
186
void
DecRef
()
187
{
188
if
(this->
Refs_
.fetch_sub (1) == 1)
189
Handle_t::from_promise (*this).destroy ();
190
}
191
};
192
193
using
ResultType_t
= R;
194
195
template
<
typename
RR>
196
using
ReplaceResult_t
=
Task
<RR, Extensions...>;
197
198
template
<
template
<
typename
>
typename
F>
199
using
ApplyResult_t
=
Task<F<R>
, Extensions...>;
200
201
explicit
Task
(
const
std::coroutine_handle<promise_type>& handle)
202
: Handle_ { handle }
203
{
204
if
(handle)
205
handle.promise ().IncRef ();
206
}
207
208
~Task
() noexcept
209
{
210
if
(Handle_)
211
Handle_.promise ().DecRef ();
212
}
213
214
Task
(
const
Task
& other)
215
: Handle_ { other.Handle_ }
216
{
217
if
(Handle_)
218
Handle_.promise ().IncRef ();
219
}
220
221
Task
&
operator=
(
const
Task
& other)
222
{
223
Task
task { other };
224
*
this
= std::move (task);
225
return
*
this
;
226
}
227
228
Task
(
Task
&& other)
noexcept
229
{
230
std::swap (Handle_, other.Handle_);
231
}
232
233
Task
&
operator=
(
Task
&& other)
noexcept
234
{
235
std::swap (Handle_, other.Handle_);
236
return
*
this
;
237
}
238
239
auto
operator
co_await
()
const
noexcept
240
{
241
return
detail::TaskAwaiter<promise_type>
{ Handle_ };
242
}
243
};
244
245
namespace
detail
246
{
247
template
<
typename
R,
template
<
typename
>
typename
... Extensions>
248
struct
GetPromise
249
{
250
using
Promise
=
typename
Task
<R, Extensions...>::promise_type;
251
Promise
*
Promise_
=
nullptr
;
252
253
bool
await_ready
() const noexcept {
return
false
; }
254
255
bool
await_suspend
(std::coroutine_handle<Promise> handle)
noexcept
256
{
257
Promise_
= &handle.promise ();
258
return
false
;
259
}
260
261
decltype
(
auto
)
await_resume
()
const
noexcept
262
{
263
return
*
Promise_
;
264
}
265
};
266
}
267
}
LC::Util::Task
Definition
task.h:151
LC::Util::Task< T, SharedTaskExtension >::ResultType_t
T ResultType_t
Definition
task.h:193
LC::Util::Task::operator=
Task & operator=(const Task &other)
Definition
task.h:221
LC::Util::Task::Task
Task(Task &&other) noexcept
Definition
task.h:228
LC::Util::Task::~Task
~Task() noexcept
Definition
task.h:208
LC::Util::Task< T, SharedTaskExtension >::ApplyResult_t
Task< F< T >, SharedTaskExtension... > ApplyResult_t
Definition
task.h:199
LC::Util::Task< T, SharedTaskExtension >::ReplaceResult_t
Task< RR, SharedTaskExtension... > ReplaceResult_t
Definition
task.h:196
LC::Util::Task::Task
Task(const Task &other)
Definition
task.h:214
LC::Util::Task::Task
Task(const std::coroutine_handle< promise_type > &handle)
Definition
task.h:201
defaulthandlers.h
finalsuspender.h
LC::Util::detail
Definition
fancytrayiconfreedesktop.cpp:24
LC::Util
Definition
icoreproxy.h:34
LC::Util::Task::promise_type
Definition
task.h:164
LC::Util::Task::promise_type::initial_suspend
std::suspend_never initial_suspend() const noexcept
Definition
task.h:172
LC::Util::Task::promise_type::GetAddress
auto GetAddress()
Definition
task.h:165
LC::Util::Task::promise_type::IncRef
void IncRef()
Definition
task.h:181
LC::Util::Task::promise_type::final_suspend
auto final_suspend() noexcept
Definition
task.h:174
LC::Util::Task::promise_type::DecRef
void DecRef()
Definition
task.h:186
LC::Util::Task::promise_type::unhandled_exception
void unhandled_exception()
Definition
task.h:176
LC::Util::Task::promise_type::get_return_object
Task get_return_object()
Definition
task.h:167
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:60
LC::Util::detail::FinalSuspender
Definition
finalsuspender.h:18
LC::Util::detail::GetPromise
Definition
task.h:249
LC::Util::detail::GetPromise::await_ready
bool await_ready() const noexcept
Definition
task.h:253
LC::Util::detail::GetPromise::await_resume
decltype(auto) await_resume() const noexcept
Definition
task.h:261
LC::Util::detail::GetPromise::await_suspend
bool await_suspend(std::coroutine_handle< Promise > handle) noexcept
Definition
task.h:255
LC::Util::detail::GetPromise::Promise
typename Task< R, Extensions... >::promise_type Promise
Definition
task.h:250
LC::Util::detail::GetPromise::Promise_
Promise * Promise_
Definition
task.h:251
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::PromiseRet< void >::IsVoid
static constexpr bool IsVoid
Definition
task.h:49
LC::Util::detail::PromiseRet< void >::Done_
bool Done_
Definition
task.h:51
LC::Util::detail::PromiseRet< void >::return_void
void return_void(this auto &&self) noexcept
Definition
task.h:53
LC::Util::detail::PromiseRet
Definition
task.h:31
LC::Util::detail::PromiseRet::Ret_
std::optional< R > Ret_
Definition
task.h:36
LC::Util::detail::PromiseRet::IsVoid
static constexpr bool IsVoid
Definition
task.h:34
LC::Util::detail::PromiseRet::ReturnType_t
R ReturnType_t
Definition
task.h:32
LC::Util::detail::PromiseRet::return_value
void return_value(this auto &&self, U &&val)
Definition
task.h:39
LC::Util::detail::TaskAwaiter
Definition
task.h:64
LC::Util::detail::TaskAwaiter::await_ready
bool await_ready() const noexcept
Definition
task.h:100
LC::Util::detail::TaskAwaiter::TaskAwaiter
TaskAwaiter(Handle_t subtask)
Definition
task.h:70
LC::Util::detail::TaskAwaiter::await_resume
auto await_resume()
Definition
task.h:119
LC::Util::detail::TaskAwaiter::Handle_t
std::coroutine_handle< Promise > Handle_t
Definition
task.h:65
LC::Util::detail::TaskAwaiter::operator=
TaskAwaiter & operator=(const TaskAwaiter &)=delete
LC::Util::detail::TaskAwaiter::Subtask_
Handle_t Subtask_
Definition
task.h:66
LC::Util::detail::TaskAwaiter::TaskAwaiter
TaskAwaiter(TaskAwaiter &&other) noexcept
Definition
task.h:77
LC::Util::detail::TaskAwaiter::await_suspend
bool await_suspend(std::coroutine_handle<> handle)
Definition
task.h:107
LC::Util::detail::TaskAwaiter::TaskAwaiter
TaskAwaiter(const TaskAwaiter &)=delete
LC::Util::detail::TaskAwaiter::OuterTask_
std::coroutine_handle OuterTask_
Definition
task.h:68
LC::Util::detail::TaskAwaiter::~TaskAwaiter
~TaskAwaiter()
Definition
task.h:87
taskfwd.h
src
util
threads
coro
task.h
Generated by
1.17.0