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