userver: userver/engine/task/shared_task_with_result.hpp Source File
Loading...
Searching...
No Matches
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/// @brief Asynchronous task with result that has a shared ownership of payload
23///
24/// ## Example usage:
25///
26/// @snippet engine/task/shared_task_with_result_test.cpp Sample SharedTaskWithResult usage
27///
28/// @see @ref scripts/docs/en/userver/synchronization.md
29template <typename T>
30class [[nodiscard]] SharedTaskWithResult : public SharedTask {
31public:
32 /// @brief Default constructor
33 ///
34 /// Creates an invalid task.
36
37 /// @brief If the task is still valid and is not finished and this is the last
38 /// shared owner of the payload, cancels the task and waits until it finishes.
40
41 /// @brief Assigns the other task into this.
43
44 /// @brief If this task is still valid and is not finished and other task is
45 /// not the same task as this and this is the
46 /// last shared owner of the payload, cancels the task and waits until it
47 /// finishes before assigning the other. Otherwise just assigns the other task
48 /// into this.
50
51 /// @brief Moves the other task into this, leaving the other in an invalid
52 /// state.
53 SharedTaskWithResult(SharedTaskWithResult&& other) noexcept = default;
54
55 /// @brief If this task is still valid and is not finished and other task is
56 /// not the same task as this and this is the
57 /// last shared owner of the payload, cancels the task and waits until it
58 /// finishes before move assigning the other. Otherwise just move assigns the
59 /// other task into this, leaving the other in an invalid state.
60 SharedTaskWithResult& operator=(SharedTaskWithResult&& other) noexcept = default;
61
62 /// @brief Returns (or rethrows) the result of task invocation.
63 /// Task remains valid after return from this method,
64 /// thread(coro)-safe.
65 /// @returns const T& or void
66 /// @throws WaitInterruptedException when `current_task::IsCancelRequested()`
67 /// and no TaskCancellationBlockers are present.
68 /// @throws TaskCancelledException
69 /// if no result is available because the task was cancelled
70 decltype(auto) Get() const& noexcept(false) {
72
73 Wait();
76 }
77
78 return utils::impl::CastWrappedCall<T>(GetPayload()).Get();
79 }
80
81 std::add_lvalue_reference<const T> Get() && {
82 static_assert(!sizeof(T*), "Store SharedTaskWithResult before using");
83 }
84
85 /// @cond
86 static constexpr WaitMode kWaitMode = WaitMode::kMultipleAwaiters;
87
88 // For internal use only.
89 explicit SharedTaskWithResult(impl::TaskContextHolder&& context)
90 : SharedTask(std::move(context))
91 {}
92 /// @endcond
93};
94
95} // namespace engine
96
97USERVER_NAMESPACE_END