LeechCraft
0.6.70-18450-gabe19ee3b0
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 "
taskfwd.h
"
17
18
namespace
LC::Util
19
{
20
namespace
detail
21
{
22
struct
PromiseBase
23
{
24
std::atomic<size_t>
Refs_
= 1;
25
std::atomic<std::coroutine_handle<>>
Continuation_
{};
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
explicit
TaskAwaiter
(
Handle_t
subtask)
69
:
Subtask_
{ subtask }
70
{
71
}
72
73
TaskAwaiter
(
TaskAwaiter
&& other) noexcept
74
:
Subtask_
{ std::exchange (other.Subtask_, {}) }
75
{
76
}
77
78
TaskAwaiter
(
const
TaskAwaiter
&) =
delete
;
79
TaskAwaiter
&
operator=
(
const
TaskAwaiter
&) =
delete
;
80
TaskAwaiter
&
operator=
(
TaskAwaiter
&& other) =
delete
;
81
82
~TaskAwaiter
()
83
{
84
if
(
Subtask_
)
85
Subtask_
.promise ().Continuation_.exchange ({});
86
}
87
88
bool
await_ready
() const noexcept
89
{
90
const
auto
& promise =
Subtask_
.promise ();
91
std::lock_guard guard { promise };
92
return
CheckTaskFinishedUnlocked (promise);
93
}
94
95
bool
await_suspend
(std::coroutine_handle<> handle)
96
{
97
auto
& promise =
Subtask_
.promise ();
98
std::lock_guard guard { promise };
99
if
(CheckTaskFinishedUnlocked (promise))
100
return
false
;
101
102
if
(promise.Continuation_.exchange (handle))
103
qFatal () <<
"subtask has already been awaited on"
;
104
return
true
;
105
}
106
107
auto
await_resume
()
108
{
109
const
auto
& promise =
Subtask_
.promise ();
110
std::lock_guard guard { promise };
111
if
(promise.Exception_)
112
try
113
{
114
std::rethrow_exception (promise.Exception_);
115
}
116
catch
(
const
EitherFailureAbort
&)
117
{
118
}
119
120
if
constexpr
(!Promise::IsVoid)
121
return
*promise.Ret_;
122
}
123
private
:
124
bool
CheckTaskFinishedUnlocked (
const
Promise& promise)
const
125
{
126
if
(promise.Exception_)
127
return
true
;
128
129
if
constexpr
(Promise::IsVoid)
130
return
promise.Done_;
131
else
132
return
static_cast<
bool
>
(promise.Ret_);
133
}
134
};
135
}
136
137
template
<
typename
>
138
struct
ThreadSafetyExtension
139
{
140
mutable
std::mutex
Mutex_
;
141
142
void
DoLock
()
const
143
{
144
Mutex_
.lock ();
145
}
146
147
void
DoUnlock
()
const
148
{
149
Mutex_
.unlock ();
150
}
151
};
152
153
template
<
typename
R,
template
<
typename
>
typename
... Extensions>
154
class
Task
155
{
156
public
:
157
struct
promise_type
;
158
private
:
159
using
Handle_t = std::coroutine_handle<promise_type>;
160
Handle_t Handle_;
161
public
:
162
struct
promise_type
:
detail::PromiseRet
<R>
163
, Extensions<promise_type>...
164
{
165
void
lock
()
const
166
{
167
if
constexpr
(
requires
{ this->DoLock (); })
168
this->DoLock ();
169
}
170
171
void
unlock
()
const
172
{
173
if
constexpr
(
requires
{ this->DoUnlock (); })
174
this->DoUnlock ();
175
}
176
177
auto
GetAddress
() {
return
Handle_t::from_promise (*this).address (); }
178
179
Task
get_return_object
()
180
{
181
return
Task
{ Handle_t::from_promise (*
this
) };
182
}
183
184
std::suspend_never
initial_suspend
() const noexcept {
return
{}; }
185
186
auto
final_suspend
() noexcept
187
{
188
([
this
]
189
{
190
static_cast<
void
>
(
this
);
191
using
Base = Extensions<promise_type>;
192
if
constexpr
(
requires
(Base t) { t.FinalSuspend (); })
193
Base::FinalSuspend ();
194
} (), ...);
195
return
detail::FinalSuspender<promise_type>
{ *
this
};
196
}
197
198
void
unhandled_exception
()
199
{
200
this->
Exception_
= std::current_exception ();
201
}
202
203
void
IncRef
()
204
{
205
this->
Refs_
.fetch_add (1);
206
}
207
208
void
DecRef
()
209
{
210
if
(this->
Refs_
.fetch_sub (1) == 1)
211
Handle_t::from_promise (*this).destroy ();
212
}
213
};
214
215
using
ResultType_t
= R;
216
217
template
<
typename
RR>
218
using
ReplaceResult_t
=
Task
<RR, Extensions...>;
219
220
template
<
template
<
typename
>
typename
F>
221
using
ApplyResult_t
=
Task<F<R>
, Extensions...>;
222
223
explicit
Task
(
const
std::coroutine_handle<promise_type>& handle)
224
: Handle_ { handle }
225
{
226
if
(handle)
227
handle.promise ().IncRef ();
228
}
229
230
~Task
() noexcept
231
{
232
if
(Handle_)
233
Handle_.promise ().DecRef ();
234
}
235
236
Task
(
const
Task
& other)
237
: Handle_ { other.Handle_ }
238
{
239
if
(Handle_)
240
Handle_.promise ().IncRef ();
241
}
242
243
Task
&
operator=
(
const
Task
& other)
244
{
245
Task
task { other };
246
*
this
= std::move (task);
247
return
*
this
;
248
}
249
250
Task
(
Task
&& other)
noexcept
251
{
252
std::swap (Handle_, other.Handle_);
253
}
254
255
Task
&
operator=
(
Task
&& other)
noexcept
256
{
257
std::swap (Handle_, other.Handle_);
258
return
*
this
;
259
}
260
261
auto
operator
co_await
()
const
noexcept
262
{
263
return
detail::TaskAwaiter<promise_type>
{ Handle_ };
264
}
265
};
266
267
namespace
detail
268
{
269
template
<
typename
R,
template
<
typename
>
typename
... Extensions>
270
struct
GetPromise
271
{
272
using
Promise
=
typename
Task
<R, Extensions...>::promise_type;
273
Promise
*
Promise_
=
nullptr
;
274
275
bool
await_ready
() const noexcept {
return
false
; }
276
277
bool
await_suspend
(std::coroutine_handle<Promise> handle)
noexcept
278
{
279
Promise_
= &handle.promise ();
280
return
false
;
281
}
282
283
decltype
(
auto
)
await_resume
()
const
noexcept
284
{
285
return
*
Promise_
;
286
}
287
};
288
}
289
}
LC::Util::Task
Definition
task.h:155
LC::Util::Task::ResultType_t
R ResultType_t
Definition
task.h:215
LC::Util::Task::operator=
Task & operator=(const Task &other)
Definition
task.h:243
LC::Util::Task::Task
Task(Task &&other) noexcept
Definition
task.h:250
LC::Util::Task::~Task
~Task() noexcept
Definition
task.h:230
LC::Util::Task< RR, Extensions... >::ApplyResult_t
Task< F< RR >, Extensions... > ApplyResult_t
Definition
task.h:221
LC::Util::Task::ReplaceResult_t
Task< RR, Extensions... > ReplaceResult_t
Definition
task.h:218
LC::Util::Task::Task
Task(const Task &other)
Definition
task.h:236
LC::Util::Task::Task
Task(const std::coroutine_handle< promise_type > &handle)
Definition
task.h:223
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:184
LC::Util::Task::promise_type::unlock
void unlock() const
Definition
task.h:171
LC::Util::Task::promise_type::GetAddress
auto GetAddress()
Definition
task.h:177
LC::Util::Task::promise_type::IncRef
void IncRef()
Definition
task.h:203
LC::Util::Task::promise_type::final_suspend
auto final_suspend() noexcept
Definition
task.h:186
LC::Util::Task::promise_type::DecRef
void DecRef()
Definition
task.h:208
LC::Util::Task::promise_type::unhandled_exception
void unhandled_exception()
Definition
task.h:198
LC::Util::Task::promise_type::get_return_object
Task get_return_object()
Definition
task.h:179
LC::Util::Task::promise_type::lock
void lock() const
Definition
task.h:165
LC::Util::ThreadSafetyExtension
Definition
task.h:139
LC::Util::ThreadSafetyExtension::DoLock
void DoLock() const
Definition
task.h:142
LC::Util::ThreadSafetyExtension::Mutex_
std::mutex Mutex_
Definition
task.h:140
LC::Util::ThreadSafetyExtension::DoUnlock
void DoUnlock() const
Definition
task.h:147
LC::Util::detail::EitherFailureAbort
Definition
task.h:60
LC::Util::detail::FinalSuspender
Definition
finalsuspender.h:17
LC::Util::detail::GetPromise
Definition
task.h:271
LC::Util::detail::GetPromise::await_ready
bool await_ready() const noexcept
Definition
task.h:275
LC::Util::detail::GetPromise::await_resume
decltype(auto) await_resume() const noexcept
Definition
task.h:283
LC::Util::detail::GetPromise::await_suspend
bool await_suspend(std::coroutine_handle< Promise > handle) noexcept
Definition
task.h:277
LC::Util::detail::GetPromise::Promise
typename Task< R, Extensions... >::promise_type Promise
Definition
task.h:272
LC::Util::detail::GetPromise::Promise_
Promise * Promise_
Definition
task.h:273
LC::Util::detail::PromiseBase
Definition
task.h:23
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:24
LC::Util::detail::PromiseBase::Continuation_
std::atomic< std::coroutine_handle<> > Continuation_
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:88
LC::Util::detail::TaskAwaiter::TaskAwaiter
TaskAwaiter(Handle_t subtask)
Definition
task.h:68
LC::Util::detail::TaskAwaiter::await_resume
auto await_resume()
Definition
task.h:107
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:73
LC::Util::detail::TaskAwaiter::await_suspend
bool await_suspend(std::coroutine_handle<> handle)
Definition
task.h:95
LC::Util::detail::TaskAwaiter::TaskAwaiter
TaskAwaiter(const TaskAwaiter &)=delete
LC::Util::detail::TaskAwaiter::~TaskAwaiter
~TaskAwaiter()
Definition
task.h:82
taskfwd.h
src
util
threads
coro
task.h
Generated by
1.17.0