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 kAbandoned, ///< Task destructor is called before the payload finished
26 kShutdown, ///< Task processor shutdown
27};
28
29class Task;
30class TaskCancellationToken;
31
32namespace current_task {
33
34/// Checks for pending cancellation requests, use
35/// engine::current_task::ShouldCancel() instead, as the latter respects
36/// engine::TaskCancellationBlocker.
37///
38/// @see @ref task_cancellation_intro
39bool IsCancelRequested() noexcept;
40
41/// Checks for pending *non-blocked* cancellation requests
42///
43/// @see engine::TaskCancellationBlocker
44/// @see @ref task_cancellation_intro
45bool ShouldCancel() noexcept;
46
47/// Returns task cancellation reason for the current task
48/// @see @ref task_cancellation_intro
50
51/// @brief \b Throws an exception if a cancellation request for this task is
52/// pending.
53///
54/// @throws unspecified (non-std) exception if cancellation is pending and not
55/// blocked
56///
57/// @warning catching this exception without a rethrow in the same scope leads
58/// to undefined behavior.
59/// @see @ref task_cancellation_intro
61
62/// Set deadline for the current task.
63/// The task will be cancelled when the deadline is reached.
64void SetDeadline(Deadline deadline);
65
66/// Return cancellation token for current coroutine.
67TaskCancellationToken GetCancellationToken();
68
69/// @see engine::Task::RequestCancel
71
72} // namespace current_task
73
74/// Blocks cancellation for specific scopes, e.g. destructors.
75/// Recursive, i.e. can be instantiated multiple times in a given call stack.
76class TaskCancellationBlocker final {
77public:
78 TaskCancellationBlocker();
79 ~TaskCancellationBlocker();
80
81 TaskCancellationBlocker(const TaskCancellationBlocker&) = delete;
82 TaskCancellationBlocker(TaskCancellationBlocker&&) = delete;
83 TaskCancellationBlocker& operator=(const TaskCancellationBlocker&) = delete;
84 TaskCancellationBlocker& operator=(TaskCancellationBlocker&&) = delete;
85
86private:
87 impl::TaskContext& context_;
88 const bool was_allowed_;
89};
90
91/// Returns a string representation of a cancellation reason
93
94/// @brief Cancellation token to given task object
95///
96/// Unlike Task, TaskCancellationToken object doesn't wait for task finish in
97/// its destructor. It is allowed to outlive the task object it was created
98/// from. However, as long as there is any cancellation token associated with
99/// given task, some internal structures of a task will not be freed.
100///
101/// General rule: whenever possible, prefer using engine::Task object instead.
102class TaskCancellationToken final {
103public:
104 /// Creates an invalid TaskCancellationToken
106
107 /// Creates a TaskCancellationToken associated with a task. The task must be
108 /// valid.
110
111 TaskCancellationToken(const TaskCancellationToken&) noexcept;
112 TaskCancellationToken(TaskCancellationToken&&) noexcept;
113 TaskCancellationToken& operator=(const TaskCancellationToken&) noexcept;
114 TaskCancellationToken& operator=(TaskCancellationToken&&) noexcept;
115 ~TaskCancellationToken();
116
117 /// @see engine::Task::RequestCancel
118 /// This method should not be called on invalid TaskCancellationToken
120
121 /// True if this token is associated with a task
122 bool IsValid() const noexcept;
123
124private:
125 friend TaskCancellationToken current_task::GetCancellationToken();
126
127 explicit TaskCancellationToken(impl::TaskContext& context) noexcept;
128
129 boost::intrusive_ptr<impl::TaskContext> context_;
130};
131
132} // namespace engine
133
134USERVER_NAMESPACE_END