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