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