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