xref: /aosp_15_r20/external/cronet/base/threading/sequence_local_storage_map.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2017 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/threading/sequence_local_storage_map.h"
6 
7 #include <ostream>
8 #include <utility>
9 
10 #include "base/check_op.h"
11 #include "base/sequence_token.h"
12 #include "third_party/abseil-cpp/absl/base/attributes.h"
13 
14 namespace base {
15 namespace internal {
16 
17 namespace {
18 
19 ABSL_CONST_INIT thread_local SequenceLocalStorageMap*
20     current_sequence_local_storage = nullptr;
21 
22 }  // namespace
23 
24 SequenceLocalStorageMap::SequenceLocalStorageMap() = default;
25 
26 SequenceLocalStorageMap::~SequenceLocalStorageMap() = default;
27 
28 // static
GetForCurrentThread()29 SequenceLocalStorageMap& SequenceLocalStorageMap::GetForCurrentThread() {
30   CHECK(!CurrentTaskIsRunningSynchronously());
31   DCHECK(IsSetForCurrentThread())
32       << "SequenceLocalStorageSlot cannot be used because no "
33          "SequenceLocalStorageMap was stored in TLS. Use "
34          "ScopedSetSequenceLocalStorageMapForCurrentThread to store a "
35          "SequenceLocalStorageMap object in TLS.";
36 
37   return *current_sequence_local_storage;
38 }
39 
40 // static
IsSetForCurrentThread()41 bool SequenceLocalStorageMap::IsSetForCurrentThread() {
42   return current_sequence_local_storage != nullptr;
43 }
44 
Has(int slot_id) const45 bool SequenceLocalStorageMap::Has(int slot_id) const {
46   return const_cast<SequenceLocalStorageMap*>(this)->Get(slot_id) != nullptr;
47 }
48 
Reset(int slot_id)49 void SequenceLocalStorageMap::Reset(int slot_id) {
50   sls_map_.erase(slot_id);
51 }
52 
Get(int slot_id)53 SequenceLocalStorageMap::Value* SequenceLocalStorageMap::Get(int slot_id) {
54   auto it = sls_map_.find(slot_id);
55   if (it != sls_map_.end()) {
56     return it->second.get();
57   }
58   return nullptr;
59 }
60 
Set(int slot_id,SequenceLocalStorageMap::ValueDestructorPair value_destructor_pair)61 SequenceLocalStorageMap::Value* SequenceLocalStorageMap::Set(
62     int slot_id,
63     SequenceLocalStorageMap::ValueDestructorPair value_destructor_pair) {
64   auto it = sls_map_.find(slot_id);
65 
66   if (it == sls_map_.end())
67     it = sls_map_.emplace(slot_id, std::move(value_destructor_pair)).first;
68   else
69     it->second = std::move(value_destructor_pair);
70 
71   // The maximum number of entries in the map is 256. This can be adjusted, but
72   // will require reviewing the choice of data structure for the map.
73   DCHECK_LE(sls_map_.size(), 256U);
74   return it->second.get();
75 }
76 
ValueDestructorPair()77 SequenceLocalStorageMap::ValueDestructorPair::ValueDestructorPair()
78     : destructor_(nullptr) {}
79 
ValueDestructorPair(ExternalValue value,DestructorFunc * destructor)80 SequenceLocalStorageMap::ValueDestructorPair::ValueDestructorPair(
81     ExternalValue value,
82     DestructorFunc* destructor)
83     : value_{.external_value = std::move(value)}, destructor_(destructor) {}
84 
ValueDestructorPair(InlineValue value,DestructorFunc * destructor)85 SequenceLocalStorageMap::ValueDestructorPair::ValueDestructorPair(
86     InlineValue value,
87     DestructorFunc* destructor)
88     : value_{.inline_value = std::move(value)}, destructor_(destructor) {}
89 
~ValueDestructorPair()90 SequenceLocalStorageMap::ValueDestructorPair::~ValueDestructorPair() {
91   if (destructor_) {
92     destructor_(&value_);
93   }
94 }
95 
ValueDestructorPair(ValueDestructorPair && value_destructor_pair)96 SequenceLocalStorageMap::ValueDestructorPair::ValueDestructorPair(
97     ValueDestructorPair&& value_destructor_pair)
98     : value_(value_destructor_pair.value_),
99       destructor_(value_destructor_pair.destructor_) {
100   value_destructor_pair.destructor_ = nullptr;
101 }
102 
103 SequenceLocalStorageMap::ValueDestructorPair&
operator =(ValueDestructorPair && value_destructor_pair)104 SequenceLocalStorageMap::ValueDestructorPair::operator=(
105     ValueDestructorPair&& value_destructor_pair) {
106   if (this == &value_destructor_pair) {
107     return *this;
108   }
109   // Destroy |value_| before overwriting it with a new value.
110   if (destructor_) {
111     destructor_(&value_);
112   }
113   value_ = value_destructor_pair.value_;
114   destructor_ = std::exchange(value_destructor_pair.destructor_, nullptr);
115 
116   return *this;
117 }
118 
operator bool() const119 SequenceLocalStorageMap::ValueDestructorPair::operator bool() const {
120   return destructor_ != nullptr;
121 }
122 
123 ScopedSetSequenceLocalStorageMapForCurrentThread::
ScopedSetSequenceLocalStorageMapForCurrentThread(SequenceLocalStorageMap * sequence_local_storage)124     ScopedSetSequenceLocalStorageMapForCurrentThread(
125         SequenceLocalStorageMap* sequence_local_storage)
126     : resetter_(&current_sequence_local_storage,
127                 sequence_local_storage,
128                 nullptr) {}
129 
130 ScopedSetSequenceLocalStorageMapForCurrentThread::
131     ~ScopedSetSequenceLocalStorageMapForCurrentThread() = default;
132 
133 }  // namespace internal
134 }  // namespace base
135