blob: cf532ef16c22863644b9f1d2bb301ebd48deb1f7 [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2016 The Chromium Authors
fdorayeed5fa72016-07-26 22:28:452// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef BASE_SEQUENCE_TOKEN_H_
6#define BASE_SEQUENCE_TOKEN_H_
7
8#include "base/base_export.h"
fdorayeed5fa72016-07-26 22:28:459
François Doray2bd91ed2024-02-16 15:30:4510namespace base {
11namespace internal {
fdorayeed5fa72016-07-26 22:28:4512
François Doray524d2a22024-01-04 09:54:1613// A token that identifies a series of sequenced work items (i.e. tasks, native
14// message handlers, code blocks running outside or a `RunLoop`, etc. that are
15// mutually exclusive).
fdorayeed5fa72016-07-26 22:28:4516class BASE_EXPORT SequenceToken {
17 public:
18 // Instantiates an invalid SequenceToken.
Peter Kasting960e2d32023-03-14 17:18:4119 constexpr SequenceToken() = default;
fdorayeed5fa72016-07-26 22:28:4520
21 // Explicitly allow copy.
22 SequenceToken(const SequenceToken& other) = default;
23 SequenceToken& operator=(const SequenceToken& other) = default;
24
25 // An invalid SequenceToken is not equal to any other SequenceToken, including
26 // other invalid SequenceTokens.
27 bool operator==(const SequenceToken& other) const;
fdorayeed5fa72016-07-26 22:28:4528
29 // Returns true if this is a valid SequenceToken.
30 bool IsValid() const;
31
gabb7555072016-10-06 21:16:2432 // Returns the integer uniquely representing this SequenceToken. This method
33 // should only be used for tracing and debugging.
34 int ToInternalValue() const;
35
fdorayeed5fa72016-07-26 22:28:4536 // Returns a valid SequenceToken which isn't equal to any previously returned
37 // SequenceToken.
38 static SequenceToken Create();
39
François Doray524d2a22024-01-04 09:54:1640 // Returns the `SequenceToken` for the work item currently running on this
41 // thread. A valid and unique `SequenceToken` is assigned to each thread. It
42 // can be overridden in a scope with `TaskScope`.
fdorayeed5fa72016-07-26 22:28:4543 static SequenceToken GetForCurrentThread();
44
45 private:
gabaa8b5972016-08-10 02:46:4746 explicit SequenceToken(int token) : token_(token) {}
fdorayeed5fa72016-07-26 22:28:4547
48 static constexpr int kInvalidSequenceToken = -1;
49 int token_ = kInvalidSequenceToken;
50};
51
fdorayb339954b2016-08-09 21:49:2652// A token that identifies a task.
53//
54// This is used by ThreadCheckerImpl to determine whether calls to
55// CalledOnValidThread() come from the same task and hence are deterministically
56// single-threaded (vs. calls coming from different sequenced or parallel tasks,
57// which may or may not run on the same thread).
58class BASE_EXPORT TaskToken {
59 public:
60 // Instantiates an invalid TaskToken.
Peter Kasting960e2d32023-03-14 17:18:4161 constexpr TaskToken() = default;
fdorayb339954b2016-08-09 21:49:2662
63 // Explicitly allow copy.
64 TaskToken(const TaskToken& other) = default;
65 TaskToken& operator=(const TaskToken& other) = default;
66
67 // An invalid TaskToken is not equal to any other TaskToken, including
68 // other invalid TaskTokens.
69 bool operator==(const TaskToken& other) const;
70 bool operator!=(const TaskToken& other) const;
71
72 // Returns true if this is a valid TaskToken.
73 bool IsValid() const;
74
François Doray524d2a22024-01-04 09:54:1675 // In the scope of a `TaskScope`, returns a valid `TaskToken` which isn't
76 // equal to any `TaskToken` returned in the scope of a different `TaskScope`.
77 // Otherwise, returns an invalid `TaskToken`.
fdorayb339954b2016-08-09 21:49:2678 static TaskToken GetForCurrentThread();
79
80 private:
François Doray524d2a22024-01-04 09:54:1681 friend class TaskScope;
fdorayb339954b2016-08-09 21:49:2682
gabaa8b5972016-08-10 02:46:4783 explicit TaskToken(int token) : token_(token) {}
fdorayb339954b2016-08-09 21:49:2684
François Doray524d2a22024-01-04 09:54:1685 // Returns a valid `TaskToken` which isn't equal to any previously returned
86 // `TaskToken`. Private as it is only meant to be instantiated by `TaskScope`.
fdorayb339954b2016-08-09 21:49:2687 static TaskToken Create();
88
89 static constexpr int kInvalidTaskToken = -1;
90 int token_ = kInvalidTaskToken;
91};
92
François Doray524d2a22024-01-04 09:54:1693// Returns true if a thread checker bound in a different task than the current
94// one but on the same sequence and thread may return true from
95// `CalledOnValidSequence()`.
96bool BASE_EXPORT CurrentTaskIsThreadBound();
97
98// Identifies a scope in which a task runs.
99class BASE_EXPORT [[maybe_unused, nodiscard]] TaskScope {
fdorayeed5fa72016-07-26 22:28:45100 public:
François Doray524d2a22024-01-04 09:54:16101 // `sequence_token` identifies the series of mutually exclusive work items
102 // that this task is part of (may be unique if this task isn't mutually
103 // exclusive with any other work item). `is_thread_bound` sets the value
104 // returned by `CurrentTaskIsThreadBound()` within the scope.
François Doray2bd91ed2024-02-16 15:30:45105 // `is_running_synchronously` is true iff this is instantiated for a task run
106 // synchronously by `RunOrPostTask()`.
Lei Zhangb39481fd2025-06-26 01:03:40107 TaskScope(SequenceToken sequence_token,
108 bool is_thread_bound,
109 bool is_running_synchronously = false);
François Doray524d2a22024-01-04 09:54:16110 TaskScope(const TaskScope&) = delete;
111 TaskScope& operator=(const TaskScope&) = delete;
112 ~TaskScope();
fdorayeed5fa72016-07-26 22:28:45113
114 private:
François Doray524d2a22024-01-04 09:54:16115 const TaskToken previous_task_token_;
116 const SequenceToken previous_sequence_token_;
117 const bool previous_task_is_thread_bound_;
François Doray2bd91ed2024-02-16 15:30:45118 const bool previous_task_is_running_synchronously_;
fdorayeed5fa72016-07-26 22:28:45119};
120
François Doray2bd91ed2024-02-16 15:30:45121} // namespace internal
122
123// Returns true if the current task is run synchronously by `RunOrPostTask()`.
124bool BASE_EXPORT CurrentTaskIsRunningSynchronously();
125
126} // namespace base
fdorayeed5fa72016-07-26 22:28:45127
128#endif // BASE_SEQUENCE_TOKEN_H_