xref: /aosp_15_r20/external/cronet/base/sequence_token.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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) const26 bool SequenceToken::operator==(const SequenceToken& other) const {
27   return token_ == other.token_ && IsValid();
28 }
29 
operator !=(const SequenceToken & other) const30 bool SequenceToken::operator!=(const SequenceToken& other) const {
31   return !(*this == other);
32 }
33 
IsValid() const34 bool SequenceToken::IsValid() const {
35   return token_ != kInvalidSequenceToken;
36 }
37 
ToInternalValue() const38 int SequenceToken::ToInternalValue() const {
39   return token_;
40 }
41 
Create()42 SequenceToken SequenceToken::Create() {
43   return SequenceToken(g_sequence_token_generator.GetNext());
44 }
45 
GetForCurrentThread()46 SequenceToken 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) const54 bool TaskToken::operator==(const TaskToken& other) const {
55   return token_ == other.token_ && IsValid();
56 }
57 
operator !=(const TaskToken & other) const58 bool TaskToken::operator!=(const TaskToken& other) const {
59   return !(*this == other);
60 }
61 
IsValid() const62 bool TaskToken::IsValid() const {
63   return token_ != kInvalidTaskToken;
64 }
65 
Create()66 TaskToken TaskToken::Create() {
67   return TaskToken(g_task_token_generator.GetNext());
68 }
69 
GetForCurrentThread()70 TaskToken TaskToken::GetForCurrentThread() {
71   return current_task_token;
72 }
73 
CurrentTaskIsThreadBound()74 bool CurrentTaskIsThreadBound() {
75   return current_task_is_thread_bound;
76 }
77 
TaskScope(SequenceToken sequence_token,bool is_single_threaded,bool is_running_synchronously)78 TaskScope::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()92 TaskScope::~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()102 bool CurrentTaskIsRunningSynchronously() {
103   return internal::current_task_is_running_synchronously;
104 }
105 
106 }  // namespace base
107