1 // Copyright 2016 The Chromium Authors 2 // 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/auto_reset.h" 9 #include "base/base_export.h" 10 11 namespace base { 12 13 // A token that identifies a series of sequenced tasks (i.e. tasks that run one 14 // at a time in posting order). 15 class BASE_EXPORT SequenceToken { 16 public: 17 // Instantiates an invalid SequenceToken. 18 constexpr SequenceToken() = default; 19 20 // Explicitly allow copy. 21 SequenceToken(const SequenceToken& other) = default; 22 SequenceToken& operator=(const SequenceToken& other) = default; 23 24 // An invalid SequenceToken is not equal to any other SequenceToken, including 25 // other invalid SequenceTokens. 26 bool operator==(const SequenceToken& other) const; 27 bool operator!=(const SequenceToken& other) const; 28 29 // Returns true if this is a valid SequenceToken. 30 bool IsValid() const; 31 32 // Returns the integer uniquely representing this SequenceToken. This method 33 // should only be used for tracing and debugging. 34 int ToInternalValue() const; 35 36 // Returns a valid SequenceToken which isn't equal to any previously returned 37 // SequenceToken. 38 static SequenceToken Create(); 39 40 // Returns the SequenceToken associated with the task running on the current 41 // thread, as determined by the active ScopedSetSequenceTokenForCurrentThread 42 // if any. 43 static SequenceToken GetForCurrentThread(); 44 45 private: SequenceToken(int token)46 explicit SequenceToken(int token) : token_(token) {} 47 48 static constexpr int kInvalidSequenceToken = -1; 49 int token_ = kInvalidSequenceToken; 50 }; 51 52 // 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). 58 class BASE_EXPORT TaskToken { 59 public: 60 // Instantiates an invalid TaskToken. 61 constexpr TaskToken() = default; 62 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 75 // In the scope of a ScopedSetSequenceTokenForCurrentThread, returns a valid 76 // TaskToken which isn't equal to any TaskToken returned in the scope of a 77 // different ScopedSetSequenceTokenForCurrentThread. Otherwise, returns an 78 // invalid TaskToken. 79 static TaskToken GetForCurrentThread(); 80 81 private: 82 friend class ScopedSetSequenceTokenForCurrentThread; 83 TaskToken(int token)84 explicit TaskToken(int token) : token_(token) {} 85 86 // Returns a valid TaskToken which isn't equal to any previously returned 87 // TaskToken. This is private as it only meant to be instantiated by 88 // ScopedSetSequenceTokenForCurrentThread. 89 static TaskToken Create(); 90 91 static constexpr int kInvalidTaskToken = -1; 92 int token_ = kInvalidTaskToken; 93 }; 94 95 // Instantiate this in the scope where a single task runs. 96 class BASE_EXPORT 97 [[maybe_unused, nodiscard]] ScopedSetSequenceTokenForCurrentThread { 98 public: 99 // Throughout the lifetime of the constructed object, 100 // SequenceToken::GetForCurrentThread() will return |sequence_token| and 101 // TaskToken::GetForCurrentThread() will return a TaskToken which is not equal 102 // to any TaskToken returned in the scope of another 103 // ScopedSetSequenceTokenForCurrentThread. 104 explicit ScopedSetSequenceTokenForCurrentThread( 105 const SequenceToken& sequence_token); 106 ScopedSetSequenceTokenForCurrentThread( 107 const ScopedSetSequenceTokenForCurrentThread&) = delete; 108 ScopedSetSequenceTokenForCurrentThread& operator=( 109 const ScopedSetSequenceTokenForCurrentThread&) = delete; 110 ~ScopedSetSequenceTokenForCurrentThread(); 111 112 private: 113 const AutoReset<SequenceToken> sequence_token_resetter_; 114 const AutoReset<TaskToken> task_token_resetter_; 115 }; 116 117 } // namespace base 118 119 #endif // BASE_SEQUENCE_TOKEN_H_ 120