xref: /aosp_15_r20/external/cronet/base/sequence_token.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2016 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_SEQUENCE_TOKEN_H_
6*6777b538SAndroid Build Coastguard Worker #define BASE_SEQUENCE_TOKEN_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker // TODO: Remove this unused include once no other file indirectly depends on it.
9*6777b538SAndroid Build Coastguard Worker #include "base/auto_reset.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h"
11*6777b538SAndroid Build Coastguard Worker 
12*6777b538SAndroid Build Coastguard Worker namespace base {
13*6777b538SAndroid Build Coastguard Worker namespace internal {
14*6777b538SAndroid Build Coastguard Worker 
15*6777b538SAndroid Build Coastguard Worker // A token that identifies a series of sequenced work items (i.e. tasks, native
16*6777b538SAndroid Build Coastguard Worker // message handlers, code blocks running outside or a `RunLoop`, etc. that are
17*6777b538SAndroid Build Coastguard Worker // mutually exclusive).
18*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT SequenceToken {
19*6777b538SAndroid Build Coastguard Worker  public:
20*6777b538SAndroid Build Coastguard Worker   // Instantiates an invalid SequenceToken.
21*6777b538SAndroid Build Coastguard Worker   constexpr SequenceToken() = default;
22*6777b538SAndroid Build Coastguard Worker 
23*6777b538SAndroid Build Coastguard Worker   // Explicitly allow copy.
24*6777b538SAndroid Build Coastguard Worker   SequenceToken(const SequenceToken& other) = default;
25*6777b538SAndroid Build Coastguard Worker   SequenceToken& operator=(const SequenceToken& other) = default;
26*6777b538SAndroid Build Coastguard Worker 
27*6777b538SAndroid Build Coastguard Worker   // An invalid SequenceToken is not equal to any other SequenceToken, including
28*6777b538SAndroid Build Coastguard Worker   // other invalid SequenceTokens.
29*6777b538SAndroid Build Coastguard Worker   bool operator==(const SequenceToken& other) const;
30*6777b538SAndroid Build Coastguard Worker   bool operator!=(const SequenceToken& other) const;
31*6777b538SAndroid Build Coastguard Worker 
32*6777b538SAndroid Build Coastguard Worker   // Returns true if this is a valid SequenceToken.
33*6777b538SAndroid Build Coastguard Worker   bool IsValid() const;
34*6777b538SAndroid Build Coastguard Worker 
35*6777b538SAndroid Build Coastguard Worker   // Returns the integer uniquely representing this SequenceToken. This method
36*6777b538SAndroid Build Coastguard Worker   // should only be used for tracing and debugging.
37*6777b538SAndroid Build Coastguard Worker   int ToInternalValue() const;
38*6777b538SAndroid Build Coastguard Worker 
39*6777b538SAndroid Build Coastguard Worker   // Returns a valid SequenceToken which isn't equal to any previously returned
40*6777b538SAndroid Build Coastguard Worker   // SequenceToken.
41*6777b538SAndroid Build Coastguard Worker   static SequenceToken Create();
42*6777b538SAndroid Build Coastguard Worker 
43*6777b538SAndroid Build Coastguard Worker   // Returns the `SequenceToken` for the work item currently running on this
44*6777b538SAndroid Build Coastguard Worker   // thread. A valid and unique `SequenceToken` is assigned to each thread. It
45*6777b538SAndroid Build Coastguard Worker   // can be overridden in a scope with `TaskScope`.
46*6777b538SAndroid Build Coastguard Worker   static SequenceToken GetForCurrentThread();
47*6777b538SAndroid Build Coastguard Worker 
48*6777b538SAndroid Build Coastguard Worker  private:
SequenceToken(int token)49*6777b538SAndroid Build Coastguard Worker   explicit SequenceToken(int token) : token_(token) {}
50*6777b538SAndroid Build Coastguard Worker 
51*6777b538SAndroid Build Coastguard Worker   static constexpr int kInvalidSequenceToken = -1;
52*6777b538SAndroid Build Coastguard Worker   int token_ = kInvalidSequenceToken;
53*6777b538SAndroid Build Coastguard Worker };
54*6777b538SAndroid Build Coastguard Worker 
55*6777b538SAndroid Build Coastguard Worker // A token that identifies a task.
56*6777b538SAndroid Build Coastguard Worker //
57*6777b538SAndroid Build Coastguard Worker // This is used by ThreadCheckerImpl to determine whether calls to
58*6777b538SAndroid Build Coastguard Worker // CalledOnValidThread() come from the same task and hence are deterministically
59*6777b538SAndroid Build Coastguard Worker // single-threaded (vs. calls coming from different sequenced or parallel tasks,
60*6777b538SAndroid Build Coastguard Worker // which may or may not run on the same thread).
61*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT TaskToken {
62*6777b538SAndroid Build Coastguard Worker  public:
63*6777b538SAndroid Build Coastguard Worker   // Instantiates an invalid TaskToken.
64*6777b538SAndroid Build Coastguard Worker   constexpr TaskToken() = default;
65*6777b538SAndroid Build Coastguard Worker 
66*6777b538SAndroid Build Coastguard Worker   // Explicitly allow copy.
67*6777b538SAndroid Build Coastguard Worker   TaskToken(const TaskToken& other) = default;
68*6777b538SAndroid Build Coastguard Worker   TaskToken& operator=(const TaskToken& other) = default;
69*6777b538SAndroid Build Coastguard Worker 
70*6777b538SAndroid Build Coastguard Worker   // An invalid TaskToken is not equal to any other TaskToken, including
71*6777b538SAndroid Build Coastguard Worker   // other invalid TaskTokens.
72*6777b538SAndroid Build Coastguard Worker   bool operator==(const TaskToken& other) const;
73*6777b538SAndroid Build Coastguard Worker   bool operator!=(const TaskToken& other) const;
74*6777b538SAndroid Build Coastguard Worker 
75*6777b538SAndroid Build Coastguard Worker   // Returns true if this is a valid TaskToken.
76*6777b538SAndroid Build Coastguard Worker   bool IsValid() const;
77*6777b538SAndroid Build Coastguard Worker 
78*6777b538SAndroid Build Coastguard Worker   // In the scope of a `TaskScope`, returns a valid `TaskToken` which isn't
79*6777b538SAndroid Build Coastguard Worker   // equal to any `TaskToken` returned in the scope of a different `TaskScope`.
80*6777b538SAndroid Build Coastguard Worker   // Otherwise, returns an invalid `TaskToken`.
81*6777b538SAndroid Build Coastguard Worker   static TaskToken GetForCurrentThread();
82*6777b538SAndroid Build Coastguard Worker 
83*6777b538SAndroid Build Coastguard Worker  private:
84*6777b538SAndroid Build Coastguard Worker   friend class TaskScope;
85*6777b538SAndroid Build Coastguard Worker 
TaskToken(int token)86*6777b538SAndroid Build Coastguard Worker   explicit TaskToken(int token) : token_(token) {}
87*6777b538SAndroid Build Coastguard Worker 
88*6777b538SAndroid Build Coastguard Worker   // Returns a valid `TaskToken` which isn't equal to any previously returned
89*6777b538SAndroid Build Coastguard Worker   // `TaskToken`. Private as it is only meant to be instantiated by `TaskScope`.
90*6777b538SAndroid Build Coastguard Worker   static TaskToken Create();
91*6777b538SAndroid Build Coastguard Worker 
92*6777b538SAndroid Build Coastguard Worker   static constexpr int kInvalidTaskToken = -1;
93*6777b538SAndroid Build Coastguard Worker   int token_ = kInvalidTaskToken;
94*6777b538SAndroid Build Coastguard Worker };
95*6777b538SAndroid Build Coastguard Worker 
96*6777b538SAndroid Build Coastguard Worker // Returns true if a thread checker bound in a different task than the current
97*6777b538SAndroid Build Coastguard Worker // one but on the same sequence and thread may return true from
98*6777b538SAndroid Build Coastguard Worker // `CalledOnValidSequence()`.
99*6777b538SAndroid Build Coastguard Worker bool BASE_EXPORT CurrentTaskIsThreadBound();
100*6777b538SAndroid Build Coastguard Worker 
101*6777b538SAndroid Build Coastguard Worker // Identifies a scope in which a task runs.
102*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT [[maybe_unused, nodiscard]] TaskScope {
103*6777b538SAndroid Build Coastguard Worker  public:
104*6777b538SAndroid Build Coastguard Worker   // `sequence_token` identifies the series of mutually exclusive work items
105*6777b538SAndroid Build Coastguard Worker   // that this task is part of (may be unique if this task isn't mutually
106*6777b538SAndroid Build Coastguard Worker   // exclusive with any other work item). `is_thread_bound` sets the value
107*6777b538SAndroid Build Coastguard Worker   // returned by `CurrentTaskIsThreadBound()` within the scope.
108*6777b538SAndroid Build Coastguard Worker   // `is_running_synchronously` is true iff this is instantiated for a task run
109*6777b538SAndroid Build Coastguard Worker   // synchronously by `RunOrPostTask()`.
110*6777b538SAndroid Build Coastguard Worker   explicit TaskScope(SequenceToken sequence_token,
111*6777b538SAndroid Build Coastguard Worker                      bool is_thread_bound,
112*6777b538SAndroid Build Coastguard Worker                      bool is_running_synchronously = false);
113*6777b538SAndroid Build Coastguard Worker   TaskScope(const TaskScope&) = delete;
114*6777b538SAndroid Build Coastguard Worker   TaskScope& operator=(const TaskScope&) = delete;
115*6777b538SAndroid Build Coastguard Worker   ~TaskScope();
116*6777b538SAndroid Build Coastguard Worker 
117*6777b538SAndroid Build Coastguard Worker  private:
118*6777b538SAndroid Build Coastguard Worker   const TaskToken previous_task_token_;
119*6777b538SAndroid Build Coastguard Worker   const SequenceToken previous_sequence_token_;
120*6777b538SAndroid Build Coastguard Worker   const bool previous_task_is_thread_bound_;
121*6777b538SAndroid Build Coastguard Worker   const bool previous_task_is_running_synchronously_;
122*6777b538SAndroid Build Coastguard Worker };
123*6777b538SAndroid Build Coastguard Worker 
124*6777b538SAndroid Build Coastguard Worker }  // namespace internal
125*6777b538SAndroid Build Coastguard Worker 
126*6777b538SAndroid Build Coastguard Worker // Returns true if the current task is run synchronously by `RunOrPostTask()`.
127*6777b538SAndroid Build Coastguard Worker bool BASE_EXPORT CurrentTaskIsRunningSynchronously();
128*6777b538SAndroid Build Coastguard Worker 
129*6777b538SAndroid Build Coastguard Worker }  // namespace base
130*6777b538SAndroid Build Coastguard Worker 
131*6777b538SAndroid Build Coastguard Worker #endif  // BASE_SEQUENCE_TOKEN_H_
132