userver
C++ Async Framework
Toggle main menu visibility
Loading...
Searching...
No Matches
task_base.hpp
Go to the documentation of this file.
1
#
pragma
once
2
3
/// @file userver/engine/task/task_base.hpp
4
/// @brief @copybrief engine::TaskBase
5
6
#
include
<
chrono
>
7
#
include
<
cstdint
>
8
#
include
<
memory
>
9
#
include
<
string_view
>
10
11
#
include
<
userver
/
engine
/
deadline
.
hpp
>
12
#
include
<
userver
/
engine
/
future_status
.
hpp
>
13
#
include
<
userver
/
engine
/
task
/
cancel
.
hpp
>
14
#
include
<
userver
/
engine
/
task
/
current_task
.
hpp
>
15
#
include
<
userver
/
utils
/
fast_pimpl
.
hpp
>
16
17
USERVER_NAMESPACE_BEGIN
18
19
namespace
utils
::impl {
20
class
WrappedCallBase;
21
}
// namespace utils::impl
22
23
namespace
engine {
24
namespace
impl
{
25
class
TaskContextHolder;
26
class
TaskContext;
27
class
TaskContextAccessor;
28
class
AwaitableBase;
29
}
// namespace impl
30
31
/// @brief Base class for all the asynchronous tasks
32
/// (engine::Task, engine::SharedTask, engine::SharedTaskWithResult,
33
/// engine::TaskWithResult, dist_lock::DistLockedTask, ...).
34
class
[[nodiscard]]
TaskBase
{
35
public
:
36
/// Task importance
37
enum
class
Importance
{
38
/// Normal task
39
kNormal
,
40
41
/// Critical task. The task will be started regardless of cancellations,
42
/// e.g. due to user request, deadline or TaskProcessor overload. After the
43
/// task starts, it may be cancelled. In particular, if it received any
44
/// cancellation requests before starting, then it will start as cancelled.
45
kCritical
,
46
};
47
48
/// Task state
49
enum
class
State
:
std
::
uint8_t
{
50
kInvalid
,
///< Unusable
51
kNew
,
///< just created, not registered with task processor
52
kQueued
,
///< awaits execution
53
kRunning
,
///< executing user code
54
kSuspended
,
///< suspended, e.g. waiting for blocking call to complete
55
56
/// The task is cancelled and was finished without returning a value or throwing a user-provided exception.
57
///
58
/// This can happen for two reasons:
59
///
60
/// 1. When a non-critical task (see @ref Importance::kCritical, see @ref flavors_of_async) is cancelled before
61
/// it starts running, the task functor is skipped, only destructor is executed. This can be interpreted
62
/// as every non-critical task having an implicit cancellation point at its start.
63
/// See more details and examples in @ref task_cancellation_before_start.
64
///
65
/// 2. When a task is cancelled because of a call to @ref engine::current_task::CancellationPoint.
66
/// This cancellation is implemented using a non-`std::exception`-based exception.
67
///
68
/// In both cases, @ref engine::TaskWithResult::Get throws @ref engine::TaskCancelledException.
69
///
70
/// Unintuitively, this status is not set when the task was cancelled after it started running,
71
/// which caused the user code to exit early.
72
///
73
/// Use @ref TaskBase::CancellationReason instead to check whether the task was cancelled.
74
kCancelled
,
75
76
/// Exited user code with return or throw.
77
///
78
/// This includes cases where the task was cancelled after it started running,
79
/// which caused the user code to exit early.
80
///
81
/// Use @ref TaskBase::IsFinished instead to check whether the task finished execution.
82
kCompleted
,
83
};
84
85
/// Task wait mode
86
enum
class
WaitMode
{
87
/// Can be awaited by at most one task at a time
88
kSingleAwaiter
,
89
/// Can be awaited by multiple tasks simultaneously
90
kMultipleAwaiters
91
};
92
93
/// @brief Checks whether this object owns an actual task (not @ref State::kInvalid)
94
///
95
/// An invalid task cannot be used. The task becomes invalid after each of the following calls:
96
///
97
/// 1. the default constructor
98
/// 2. moving from this task object
99
/// 3. @ref engine::TaskWithResult::Get
100
/// 4. @ref concurrent::BackgroundTaskStorageCore::Detach
101
/// 5. @ref engine::DetachUnscopedUnsafe
102
///
103
/// Notably, the task does *not* become invalid immediately after it finishes execution.
104
/// (That would always cause race conditions when trying to await a task.)
105
/// It means that some of the task's resources are held onto until the task object is invalidated or destroyed.
106
bool
IsValid
()
const
;
107
108
/// Gets the task State
109
State
GetState
()
const
;
110
111
static
std::string_view GetStateName(
State
state);
112
113
/// Returns whether the task finished execution
114
bool
IsFinished
()
const
;
115
116
/// @brief Suspends execution until the task finishes or caller is cancelled.
117
/// Can be called from coroutine context only. For non-coroutine context use
118
/// BlockingWait().
119
/// @throws WaitInterruptedException when `current_task::IsCancelRequested()`
120
/// and no TaskCancellationBlockers are present.
121
void
Wait
()
const
noexcept
(
false
);
122
123
/// @brief Suspends execution until the task finishes or after the specified
124
/// timeout or until caller is cancelled
125
/// @throws WaitInterruptedException when `current_task::IsCancelRequested()`
126
/// and no TaskCancellationBlockers are present.
127
template
<
typename
Rep,
typename
Period>
128
void
WaitFor
(
const
std::chrono::duration<Rep, Period>&)
const
noexcept
(
false
);
129
130
/// @brief Suspends execution until the task finishes or until the specified
131
/// time point is reached or until caller is cancelled
132
/// @throws WaitInterruptedException when `current_task::IsCancelRequested()`
133
/// and no TaskCancellationBlockers are present.
134
template
<
typename
Clock,
typename
Duration>
135
void
WaitUntil
(
const
std::chrono::time_point<Clock, Duration>&)
const
noexcept
(
false
);
136
137
/// @brief Suspends execution until the task finishes or until the specified
138
/// deadline is reached or until caller is cancelled
139
/// @throws WaitInterruptedException when `current_task::IsCancelRequested()`
140
/// and no TaskCancellationBlockers are present.
141
void
WaitUntil
(Deadline)
const
;
142
143
/// @brief Suspends execution until the task finishes or caller is cancelled.
144
/// Can be called from coroutine context only. For non-coroutine context use
145
/// BlockingWait().
146
/// @returns `false` when `current_task::IsCancelRequested()`
147
/// and no TaskCancellationBlockers are present.
148
[[
nodiscard
]]
bool
WaitNothrow
()
const
noexcept
;
149
150
/// @brief Suspends execution until the task finishes or until the specified
151
/// deadline is reached or until caller is cancelled
152
/// @returns FutureStatus::kCancelled when `current_task::IsCancelRequested()`
153
/// and no TaskCancellationBlockers are present.
154
[[
nodiscard
]]
FutureStatus
WaitNothrowUntil
(Deadline)
const
noexcept
;
155
156
/// Queues task cancellation request
157
void
RequestCancel
();
158
159
/// @brief Cancels the task and suspends execution until it is finished.
160
/// Can be called from coroutine context only. For non-coroutine context use
161
/// RequestCancel() + BlockingWait().
162
void
SyncCancel
()
noexcept
;
163
164
/// Gets task cancellation reason
165
TaskCancellationReason
CancellationReason
()
const
;
166
167
/// Waits for the task in non-coroutine context
168
/// (e.g. non-TaskProcessor's std::thread).
169
void
BlockingWait
()
const
noexcept
;
170
171
protected
:
172
/// @cond
173
// For internal use only.
174
TaskBase();
175
176
// For internal use only.
177
explicit
TaskBase(
impl
::TaskContextHolder&& context);
178
179
// The following special functions must remain protected to forbid slicing
180
// and force those methods implementation in derived classes.
181
TaskBase(
TaskBase
&&)
noexcept
;
182
TaskBase
& operator=(
TaskBase
&&)
noexcept
;
183
TaskBase(
const
TaskBase
&)
noexcept
;
184
TaskBase
& operator=(
const
TaskBase
&)
noexcept
;
185
~TaskBase();
186
187
// For internal use only.
188
impl
::TaskContext& GetContext()
const
noexcept
;
189
190
// For internal use only.
191
bool
HasSameContext(
const
TaskBase
& other)
const
noexcept
;
192
193
// For internal use only.
194
utils
::impl::WrappedCallBase& GetPayload()
const
noexcept
;
195
196
// Marks task as invalid. For internal use only.
197
void
Invalidate()
noexcept
;
198
199
void
Terminate(
TaskCancellationReason
)
noexcept
;
200
/// @endcond
201
202
private
:
203
friend
class
impl
::TaskContextAccessor;
204
205
struct
Impl;
206
utils
::FastPimpl<Impl, 8, 8> pimpl_;
207
};
208
209
template
<
typename
Rep,
typename
Period>
210
void
TaskBase
::
WaitFor
(
const
std::chrono::duration<Rep, Period>& duration)
const
noexcept
(
false
) {
211
WaitUntil(Deadline::FromDuration(duration));
212
}
213
214
template
<
typename
Clock,
typename
Duration>
215
void
TaskBase
::
WaitUntil
(
const
std::chrono::time_point<Clock, Duration>& until)
const
noexcept
(
false
) {
216
WaitUntil(Deadline::FromTimePoint(until));
217
}
218
219
}
// namespace engine
220
221
USERVER_NAMESPACE_END
userver
engine
task
task_base.hpp
Generated on
for userver by
Doxygen
1.17.0