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 #include "base/sequence_token.h" 6 7 #include "base/atomic_sequence_num.h" 8 #include "third_party/abseil-cpp/absl/base/attributes.h" 9 10 namespace base { 11 namespace internal { 12 13 namespace { 14 15 base::AtomicSequenceNumber g_sequence_token_generator; 16 17 base::AtomicSequenceNumber g_task_token_generator; 18 19 ABSL_CONST_INIT thread_local SequenceToken current_sequence_token; 20 ABSL_CONST_INIT thread_local TaskToken current_task_token; 21 ABSL_CONST_INIT thread_local bool current_task_is_thread_bound = true; 22 ABSL_CONST_INIT thread_local bool current_task_is_running_synchronously = false; 23 24 } // namespace 25 operator ==(const SequenceToken & other) const26bool SequenceToken::operator==(const SequenceToken& other) const { 27 return token_ == other.token_ && IsValid(); 28 } 29 operator !=(const SequenceToken & other) const30bool SequenceToken::operator!=(const SequenceToken& other) const { 31 return !(*this == other); 32 } 33 IsValid() const34bool SequenceToken::IsValid() const { 35 return token_ != kInvalidSequenceToken; 36 } 37 ToInternalValue() const38int SequenceToken::ToInternalValue() const { 39 return token_; 40 } 41 Create()42SequenceToken SequenceToken::Create() { 43 return SequenceToken(g_sequence_token_generator.GetNext()); 44 } 45 GetForCurrentThread()46SequenceToken SequenceToken::GetForCurrentThread() { 47 if (!current_sequence_token.IsValid()) { 48 current_sequence_token = SequenceToken::Create(); 49 DCHECK(current_task_is_thread_bound); 50 } 51 return current_sequence_token; 52 } 53 operator ==(const TaskToken & other) const54bool TaskToken::operator==(const TaskToken& other) const { 55 return token_ == other.token_ && IsValid(); 56 } 57 operator !=(const TaskToken & other) const58bool TaskToken::operator!=(const TaskToken& other) const { 59 return !(*this == other); 60 } 61 IsValid() const62bool TaskToken::IsValid() const { 63 return token_ != kInvalidTaskToken; 64 } 65 Create()66TaskToken TaskToken::Create() { 67 return TaskToken(g_task_token_generator.GetNext()); 68 } 69 GetForCurrentThread()70TaskToken TaskToken::GetForCurrentThread() { 71 return current_task_token; 72 } 73 CurrentTaskIsThreadBound()74bool CurrentTaskIsThreadBound() { 75 return current_task_is_thread_bound; 76 } 77 TaskScope(SequenceToken sequence_token,bool is_single_threaded,bool is_running_synchronously)78TaskScope::TaskScope(SequenceToken sequence_token, 79 bool is_single_threaded, 80 bool is_running_synchronously) 81 : previous_task_token_(TaskToken::GetForCurrentThread()), 82 previous_sequence_token_(SequenceToken::GetForCurrentThread()), 83 previous_task_is_thread_bound_(current_task_is_thread_bound), 84 previous_task_is_running_synchronously_( 85 current_task_is_running_synchronously) { 86 current_task_token = TaskToken::Create(); 87 current_sequence_token = sequence_token; 88 current_task_is_thread_bound = is_single_threaded; 89 current_task_is_running_synchronously = is_running_synchronously; 90 } 91 ~TaskScope()92TaskScope::~TaskScope() { 93 current_task_token = previous_task_token_; 94 current_sequence_token = previous_sequence_token_; 95 current_task_is_thread_bound = previous_task_is_thread_bound_; 96 current_task_is_running_synchronously = 97 previous_task_is_running_synchronously_; 98 } 99 100 } // namespace internal 101 CurrentTaskIsRunningSynchronously()102bool CurrentTaskIsRunningSynchronously() { 103 return internal::current_task_is_running_synchronously; 104 } 105 106 } // namespace base 107