userver
C++ Async Framework
Toggle main menu visibility
Loading...
Searching...
No Matches
task_with_result.hpp
Go to the documentation of this file.
1
#
pragma
once
2
3
/// @file userver/engine/task/task_with_result.hpp
4
/// @brief @copybrief engine::TaskWithResult
5
6
#
include
<
memory
>
7
#
include
<
stdexcept
>
8
#
include
<
utility
>
9
10
#
include
<
userver
/
engine
/
exception
.
hpp
>
11
#
include
<
userver
/
engine
/
impl
/
task_context_holder
.
hpp
>
12
#
include
<
userver
/
engine
/
task
/
task
.
hpp
>
13
#
include
<
userver
/
utils
/
fast_scope_guard
.
hpp
>
14
#
include
<
userver
/
utils
/
impl
/
wrapped_call
.
hpp
>
15
16
USERVER_NAMESPACE_BEGIN
17
18
namespace
engine {
19
20
/// Asynchronous task with result
21
///
22
/// @warning This class supports only a single concurrent awaiter. Use
23
/// @ref engine::SharedTaskWithResult to await and retrieve the same result from
24
/// multiple coroutines.
25
///
26
/// ## Example usage:
27
///
28
/// @snippet core/src/engine/task/task_with_result_test.cpp Sample TaskWithResult usage
29
///
30
/// @see @ref scripts/docs/en/userver/synchronization.md
31
template
<
typename
T>
32
class
[[nodiscard]]
TaskWithResult
:
public
Task
{
33
public
:
34
/// @brief Default constructor
35
///
36
/// Creates an invalid task.
37
TaskWithResult
() =
default
;
38
39
TaskWithResult(
const
TaskWithResult
&) =
delete
;
40
TaskWithResult
& operator=(
const
TaskWithResult
&) =
delete
;
41
42
/// @brief Moves the other task into this, leaving the other in an invalid
43
/// state.
44
TaskWithResult
(
TaskWithResult
&& other)
noexcept
=
default
;
45
46
/// @brief If this Task is still valid and is not finished, cancels it and
47
/// waits until it finishes before moving the other. Otherwise just moves the
48
/// other task into this, leaving the other in invalid state.
49
TaskWithResult
&
operator
=(
TaskWithResult
&& other)
noexcept
=
default
;
50
51
/// @brief Returns (or rethrows) the result of task invocation.
52
/// After return from this method the task is not valid.
53
/// @throws WaitInterruptedException when `current_task::IsCancelRequested()`
54
/// and no TaskCancellationBlockers are present.
55
/// @throws TaskCancelledException
56
/// if no result is available because the task was cancelled
57
T
Get
()
noexcept
(
false
) {
58
EnsureValid();
59
60
Wait
(
)
;
61
const
utils
::FastScopeGuard invalidate([
this
]()
noexcept
{ Invalidate(); });
62
if
(
GetState
(
)
==
State
::
kCancelled
) {
63
throw
TaskCancelledException
(
CancellationReason
(
)
);
64
}
65
66
return
utils
::impl::CastWrappedCall<T>(GetPayload()).Retrieve();
67
}
68
69
/// Satisfies @ref engine::Awaitable, for use with @ref engine::WaitAnyContext and friends.
70
using
Task
::GetAwaitableToken;
71
72
/// @cond
73
static
constexpr
WaitMode
kWaitMode =
WaitMode
::
kSingleAwaiter
;
74
75
// For internal use only.
76
explicit
TaskWithResult(
impl
::TaskContextHolder&& context)
77
:
Task
(std::move(context))
78
{}
79
/// @endcond
80
81
Task
AsTask() && {
82
// NOLINTNEXTLINE(cppcoreguidelines-slicing)
83
return
std::move(*
this
);
84
}
85
86
private
:
87
void
EnsureValid()
const
{
88
UINVARIANT
(
89
IsValid
(
)
,
90
"TaskWithResult::Get was called on an invalid task. Note that "
91
"Get invalidates self, so it must be called at most once "
92
"per task"
93
);
94
}
95
};
96
97
}
// namespace engine
98
99
USERVER_NAMESPACE_END
userver
engine
task
task_with_result.hpp
Generated on
for userver by
Doxygen
1.17.0