mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-12-01 01:36:09 +03:00
106 lines
3.3 KiB
C++
106 lines
3.3 KiB
C++
|
// Copyright 2017 The Chromium Authors. All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style license that can be
|
||
|
// found in the LICENSE file.
|
||
|
|
||
|
#include "base/threading/sequence_local_storage_map.h"
|
||
|
|
||
|
#include <utility>
|
||
|
|
||
|
#include "base/lazy_instance.h"
|
||
|
#include "base/logging.h"
|
||
|
#include "base/threading/thread_local.h"
|
||
|
|
||
|
namespace base {
|
||
|
namespace internal {
|
||
|
|
||
|
namespace {
|
||
|
LazyInstance<ThreadLocalPointer<SequenceLocalStorageMap>>::Leaky
|
||
|
tls_current_sequence_local_storage = LAZY_INSTANCE_INITIALIZER;
|
||
|
} // namespace
|
||
|
|
||
|
SequenceLocalStorageMap::SequenceLocalStorageMap() = default;
|
||
|
|
||
|
SequenceLocalStorageMap::~SequenceLocalStorageMap() = default;
|
||
|
|
||
|
ScopedSetSequenceLocalStorageMapForCurrentThread::
|
||
|
ScopedSetSequenceLocalStorageMapForCurrentThread(
|
||
|
SequenceLocalStorageMap* sequence_local_storage) {
|
||
|
DCHECK(!tls_current_sequence_local_storage.Get().Get());
|
||
|
tls_current_sequence_local_storage.Get().Set(sequence_local_storage);
|
||
|
}
|
||
|
|
||
|
ScopedSetSequenceLocalStorageMapForCurrentThread::
|
||
|
~ScopedSetSequenceLocalStorageMapForCurrentThread() {
|
||
|
tls_current_sequence_local_storage.Get().Set(nullptr);
|
||
|
}
|
||
|
|
||
|
SequenceLocalStorageMap& SequenceLocalStorageMap::GetForCurrentThread() {
|
||
|
SequenceLocalStorageMap* current_sequence_local_storage =
|
||
|
tls_current_sequence_local_storage.Get().Get();
|
||
|
|
||
|
DCHECK(current_sequence_local_storage)
|
||
|
<< "SequenceLocalStorageSlot cannot be used because no "
|
||
|
"SequenceLocalStorageMap was stored in TLS. Use "
|
||
|
"ScopedSetSequenceLocalStorageMapForCurrentThread to store a "
|
||
|
"SequenceLocalStorageMap object in TLS.";
|
||
|
|
||
|
return *current_sequence_local_storage;
|
||
|
}
|
||
|
|
||
|
void* SequenceLocalStorageMap::Get(int slot_id) {
|
||
|
const auto it = sls_map_.find(slot_id);
|
||
|
if (it == sls_map_.end())
|
||
|
return nullptr;
|
||
|
return it->second.value();
|
||
|
}
|
||
|
|
||
|
void SequenceLocalStorageMap::Set(
|
||
|
int slot_id,
|
||
|
SequenceLocalStorageMap::ValueDestructorPair value_destructor_pair) {
|
||
|
auto it = sls_map_.find(slot_id);
|
||
|
|
||
|
if (it == sls_map_.end())
|
||
|
sls_map_.emplace(slot_id, std::move(value_destructor_pair));
|
||
|
else
|
||
|
it->second = std::move(value_destructor_pair);
|
||
|
|
||
|
// The maximum number of entries in the map is 256. This can be adjusted, but
|
||
|
// will require reviewing the choice of data structure for the map.
|
||
|
DCHECK_LE(sls_map_.size(), 256U);
|
||
|
}
|
||
|
|
||
|
SequenceLocalStorageMap::ValueDestructorPair::ValueDestructorPair(
|
||
|
void* value,
|
||
|
DestructorFunc* destructor)
|
||
|
: value_(value), destructor_(destructor) {}
|
||
|
|
||
|
SequenceLocalStorageMap::ValueDestructorPair::~ValueDestructorPair() {
|
||
|
if (value_)
|
||
|
destructor_(value_);
|
||
|
}
|
||
|
|
||
|
SequenceLocalStorageMap::ValueDestructorPair::ValueDestructorPair(
|
||
|
ValueDestructorPair&& value_destructor_pair)
|
||
|
: value_(value_destructor_pair.value_),
|
||
|
destructor_(value_destructor_pair.destructor_) {
|
||
|
value_destructor_pair.value_ = nullptr;
|
||
|
}
|
||
|
|
||
|
SequenceLocalStorageMap::ValueDestructorPair&
|
||
|
SequenceLocalStorageMap::ValueDestructorPair::operator=(
|
||
|
ValueDestructorPair&& value_destructor_pair) {
|
||
|
// Destroy |value_| before overwriting it with a new value.
|
||
|
if (value_)
|
||
|
destructor_(value_);
|
||
|
|
||
|
value_ = value_destructor_pair.value_;
|
||
|
destructor_ = value_destructor_pair.destructor_;
|
||
|
|
||
|
value_destructor_pair.value_ = nullptr;
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
} // namespace internal
|
||
|
} // namespace base
|