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 <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/// @see engine::Task::RequestCancel
69
70/// @brief Return cancellation token for current coroutine.
71/// @note Prefer engine::current_task::RequestCancel in most cases.
72TaskCancellationToken GetCancellationToken();
73
74} // namespace current_task
75
76/// Blocks cancellation for specific scopes, e.g. destructors.
77/// Recursive, i.e. can be instantiated multiple times in a given call stack.
78class TaskCancellationBlocker final {
79public:
80 TaskCancellationBlocker();
81 ~TaskCancellationBlocker();
82
83 TaskCancellationBlocker(const TaskCancellationBlocker&) = delete;
84 TaskCancellationBlocker(TaskCancellationBlocker&&) = delete;
85 TaskCancellationBlocker& operator=(const TaskCancellationBlocker&) = delete;
86 TaskCancellationBlocker& operator=(TaskCancellationBlocker&&) = delete;
87
88private:
89 impl::TaskContext& context_;
90 const bool was_allowed_;
91};
92
93/// Returns a string representation of a cancellation reason
94std::string_view ToString(TaskCancellationReason reason) noexcept;
95
96/// @brief Cancellation token to given task object
97///
98/// Unlike Task, TaskCancellationToken object doesn't wait for task finish in
99/// its destructor. It is allowed to outlive the task object it was created
100/// from. However, as long as there is any cancellation token associated with
101/// given task, some internal structures of a task will not be freed.
102///
103/// General rule: whenever possible, prefer using engine::Task object instead.
104class TaskCancellationToken final {
105public:
106 /// Creates an invalid TaskCancellationToken
108
109 /// Creates a TaskCancellationToken associated with a task. The task must be
110 /// valid.
112
113 TaskCancellationToken(const TaskCancellationToken&) noexcept;
114 TaskCancellationToken(TaskCancellationToken&&) noexcept;
115 TaskCancellationToken& operator=(const TaskCancellationToken&) noexcept;
116 TaskCancellationToken& operator=(TaskCancellationToken&&) noexcept;
117 ~TaskCancellationToken();
118
119 /// @see engine::Task::RequestCancel
120 /// This method should not be called on invalid TaskCancellationToken
122
123 /// @see engine::Task::CancellationReason
124 /// This method should not be called on invalid TaskCancellationToken
126
127 /// @see @ref task_cancellation_intro
128 /// True if there is pending cancellation request for the associated task
129 /// This method should not be called on invalid TaskCancellationToken
130 bool IsCancelRequested() const noexcept;
131
132 /// True if this token is associated with a task
133 bool IsValid() const noexcept;
134
135private:
136 friend TaskCancellationToken current_task::GetCancellationToken();
137
138 explicit TaskCancellationToken(impl::TaskContext& context) noexcept;
139
140 boost::intrusive_ptr<impl::TaskContext> context_;
141};
142
143} // namespace engine
144
145USERVER_NAMESPACE_END