userver: userver/engine/task/shared_task_with_result.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
shared_task_with_result.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/engine/task/shared_task_with_result.hpp
4/// @brief @copybrief engine::SharedTaskWithResult
5
6#include <memory>
7#include <stdexcept>
8#include <type_traits>
9#include <utility>
10
11#include <userver/engine/exception.hpp>
12#include <userver/engine/impl/task_context_holder.hpp>
13#include <userver/engine/task/shared_task.hpp>
14#include <userver/engine/task/task_processor_fwd.hpp>
15#include <userver/utils/assert.hpp>
16#include <userver/utils/impl/wrapped_call.hpp>
17
18USERVER_NAMESPACE_BEGIN
19
20namespace engine {
21
22// clang-format off
23
24/// @brief Asynchronous task with result that has a shared ownership of payload
25///
26/// ## Example usage:
27///
28/// @snippet engine/task/shared_task_with_result_test.cpp Sample SharedTaskWithResult usage
29///
30/// @see @ref scripts/docs/en/userver/synchronization.md
31
32// clang-format on
33
34template <typename T>
35class [[nodiscard]] SharedTaskWithResult : public SharedTask {
36 public:
37 /// @brief Default constructor
38 ///
39 /// Creates an invalid task.
41
42 /// @brief If the task is still valid and is not finished and this is the last
43 /// shared owner of the payload, cancels the task and waits until it finishes.
45
46 /// @brief Assigns the other task into this.
48
49 /// @brief If this task is still valid and is not finished and other task is
50 /// not the same task as this and this is the
51 /// last shared owner of the payload, cancels the task and waits until it
52 /// finishes before assigning the other. Otherwise just assigns the other task
53 /// into this.
55
56 /// @brief Moves the other task into this, leaving the other in an invalid
57 /// state.
58 SharedTaskWithResult(SharedTaskWithResult&& other) noexcept = default;
59
60 /// @brief If this task is still valid and is not finished and other task is
61 /// not the same task as this and this is the
62 /// last shared owner of the payload, cancels the task and waits until it
63 /// finishes before move assigning the other. Otherwise just move assigns the
64 /// other task into this, leaving the other in an invalid state.
66 default;
67
68 /// @brief Returns (or rethrows) the result of task invocation.
69 /// Task remains valid after return from this method,
70 /// thread(coro)-safe.
71 /// @returns const T& or void
72 /// @throws WaitInterruptedException when `current_task::IsCancelRequested()`
73 /// and no TaskCancellationBlockers are present.
74 /// @throws TaskCancelledException
75 /// if no result is available because the task was cancelled
76 decltype(auto) Get() const& noexcept(false) {
78
79 Wait();
82 }
83
84 return utils::impl::CastWrappedCall<T>(GetPayload()).Get();
85 }
86
87 std::add_lvalue_reference<const T> Get() && {
88 static_assert(!sizeof(T*), "Store SharedTaskWithResult before using");
89 }
90
91 /// @cond
92 static constexpr WaitMode kWaitMode = WaitMode::kMultipleWaiters;
93
94 // For internal use only.
95 explicit SharedTaskWithResult(impl::TaskContextHolder&& context)
96 : SharedTask(std::move(context)) {}
97 /// @endcond
98};
99
100} // namespace engine
101
102USERVER_NAMESPACE_END