userver: userver/engine/task/cancel.hpp Source File
Loading...
Searching...
No Matches
cancel.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/engine/task/cancel.hpp
4/// @brief Task cancellation helpers
5
6#include <cstdint>
7#include <string_view>
8
9#include <boost/smart_ptr/intrusive_ptr.hpp>
10
11#include <userver/engine/deadline.hpp>
12
13USERVER_NAMESPACE_BEGIN
14
15namespace engine {
16namespace impl {
17class TaskContext;
18} // namespace impl
19
20/// Task cancellation reason
22 kNone, ///< Not cancelled
23 kUserRequest, ///< User request
24 kDeadline, ///< Deadline
25 kOverload, ///< Task processor overload
26 kOOM, ///< Not enough memory
27 kAbandoned, ///< Task destructor is called before the payload finished
28 kShutdown, ///< Task processor shutdown
29};
30
31class Task;
32class TaskCancellationToken;
33
34namespace current_task {
35
36/// Checks for pending cancellation requests, use
37/// engine::current_task::ShouldCancel() instead, as the latter respects
38/// engine::TaskCancellationBlocker.
39///
40/// @see @ref task_cancellation_intro
41bool IsCancelRequested() noexcept;
42
43/// Checks for pending *non-blocked* cancellation requests
44///
45/// @see engine::TaskCancellationBlocker
46/// @see @ref task_cancellation_intro
47bool ShouldCancel() noexcept;
48
49/// Returns task cancellation reason for the current task
50/// @see @ref task_cancellation_intro
52
53/// @brief \b Throws an exception if a cancellation request for this task is
54/// pending.
55///
56/// @throws unspecified (non-std) exception if cancellation is pending and not
57/// blocked
58///
59/// @warning catching this exception without a rethrow in the same scope leads
60/// to undefined behavior.
61/// @see @ref task_cancellation_intro
63
64/// Set deadline for the current task.
65/// The task will be cancelled when the deadline is reached.
66void SetDeadline(Deadline deadline);
67
68/// @see engine::Task::RequestCancel
70
71/// @brief Return cancellation token for current coroutine.
72/// @note Prefer engine::current_task::RequestCancel in most cases.
73TaskCancellationToken GetCancellationToken();
74
75} // namespace current_task
76
77/// Blocks cancellation for specific scopes, e.g. destructors.
78/// Recursive, i.e. can be instantiated multiple times in a given call stack.
79class TaskCancellationBlocker final {
80public:
81 TaskCancellationBlocker();
82 ~TaskCancellationBlocker();
83
84 TaskCancellationBlocker(const TaskCancellationBlocker&) = delete;
85 TaskCancellationBlocker(TaskCancellationBlocker&&) = delete;
86 TaskCancellationBlocker& operator=(const TaskCancellationBlocker&) = delete;
87 TaskCancellationBlocker& operator=(TaskCancellationBlocker&&) = delete;
88
89private:
90 impl::TaskContext& context_;
91 const bool was_allowed_;
92};
93
94/// Returns a string representation of a cancellation reason
95std::string_view ToString(TaskCancellationReason reason) noexcept;
96
97/// @brief Cancellation token to given task object
98///
99/// Unlike Task, TaskCancellationToken object doesn't wait for task finish in
100/// its destructor. It is allowed to outlive the task object it was created
101/// from. However, as long as there is any cancellation token associated with
102/// given task, some internal structures of a task will not be freed.
103///
104/// General rule: whenever possible, prefer using engine::Task object instead.
105class TaskCancellationToken final {
106public:
107 /// Creates an invalid TaskCancellationToken
109
110 /// Creates a TaskCancellationToken associated with a task. The task must be
111 /// valid.
113
114 TaskCancellationToken(const TaskCancellationToken&) noexcept;
115 TaskCancellationToken(TaskCancellationToken&&) noexcept;
116 TaskCancellationToken& operator=(const TaskCancellationToken&) noexcept;
117 TaskCancellationToken& operator=(TaskCancellationToken&&) noexcept;
118 ~TaskCancellationToken();
119
120 /// @see engine::Task::RequestCancel
121 /// This method should not be called on invalid TaskCancellationToken
123
124 /// @see engine::Task::CancellationReason
125 /// This method should not be called on invalid TaskCancellationToken
127
128 /// @see @ref task_cancellation_intro
129 /// True if there is pending cancellation request for the associated task
130 /// This method should not be called on invalid TaskCancellationToken
131 bool IsCancelRequested() const noexcept;
132
133 /// True if this token is associated with a task
134 bool IsValid() const noexcept;
135
136private:
137 friend TaskCancellationToken current_task::GetCancellationToken();
138
139 explicit TaskCancellationToken(impl::TaskContext& context) noexcept;
140
141 boost::intrusive_ptr<impl::TaskContext> context_;
142};
143
144} // namespace engine
145
146USERVER_NAMESPACE_END