sequence_local_storage_map.cc 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "base/threading/sequence_local_storage_map.h"
  5. #include <ostream>
  6. #include <utility>
  7. #include "base/check_op.h"
  8. #include "base/lazy_instance.h"
  9. #include "base/threading/thread_local.h"
  10. namespace base {
  11. namespace internal {
  12. namespace {
  13. LazyInstance<ThreadLocalPointer<SequenceLocalStorageMap>>::Leaky
  14. tls_current_sequence_local_storage = LAZY_INSTANCE_INITIALIZER;
  15. } // namespace
  16. SequenceLocalStorageMap::SequenceLocalStorageMap() = default;
  17. SequenceLocalStorageMap::~SequenceLocalStorageMap() = default;
  18. ScopedSetSequenceLocalStorageMapForCurrentThread::
  19. ScopedSetSequenceLocalStorageMapForCurrentThread(
  20. SequenceLocalStorageMap* sequence_local_storage) {
  21. DCHECK(!tls_current_sequence_local_storage.Get().Get());
  22. tls_current_sequence_local_storage.Get().Set(sequence_local_storage);
  23. }
  24. ScopedSetSequenceLocalStorageMapForCurrentThread::
  25. ~ScopedSetSequenceLocalStorageMapForCurrentThread() {
  26. tls_current_sequence_local_storage.Get().Set(nullptr);
  27. }
  28. // static
  29. SequenceLocalStorageMap& SequenceLocalStorageMap::GetForCurrentThread() {
  30. SequenceLocalStorageMap* current_sequence_local_storage =
  31. tls_current_sequence_local_storage.Get().Get();
  32. DCHECK(current_sequence_local_storage)
  33. << "SequenceLocalStorageSlot cannot be used because no "
  34. "SequenceLocalStorageMap was stored in TLS. Use "
  35. "ScopedSetSequenceLocalStorageMapForCurrentThread to store a "
  36. "SequenceLocalStorageMap object in TLS.";
  37. return *current_sequence_local_storage;
  38. }
  39. // static
  40. bool SequenceLocalStorageMap::IsSetForCurrentThread() {
  41. return tls_current_sequence_local_storage.Get().Get() != nullptr;
  42. }
  43. void* SequenceLocalStorageMap::Get(int slot_id) {
  44. const auto it = sls_map_.find(slot_id);
  45. if (it == sls_map_.end())
  46. return nullptr;
  47. return it->second.value();
  48. }
  49. void SequenceLocalStorageMap::Set(
  50. int slot_id,
  51. SequenceLocalStorageMap::ValueDestructorPair value_destructor_pair) {
  52. auto it = sls_map_.find(slot_id);
  53. if (it == sls_map_.end())
  54. sls_map_.emplace(slot_id, std::move(value_destructor_pair));
  55. else
  56. it->second = std::move(value_destructor_pair);
  57. // The maximum number of entries in the map is 256. This can be adjusted, but
  58. // will require reviewing the choice of data structure for the map.
  59. DCHECK_LE(sls_map_.size(), 256U);
  60. }
  61. SequenceLocalStorageMap::ValueDestructorPair::ValueDestructorPair(
  62. void* value,
  63. DestructorFunc* destructor)
  64. : value_(value), destructor_(destructor) {}
  65. SequenceLocalStorageMap::ValueDestructorPair::~ValueDestructorPair() {
  66. if (value_)
  67. destructor_(value_);
  68. }
  69. SequenceLocalStorageMap::ValueDestructorPair::ValueDestructorPair(
  70. ValueDestructorPair&& value_destructor_pair)
  71. : value_(value_destructor_pair.value_),
  72. destructor_(value_destructor_pair.destructor_) {
  73. value_destructor_pair.value_ = nullptr;
  74. }
  75. SequenceLocalStorageMap::ValueDestructorPair&
  76. SequenceLocalStorageMap::ValueDestructorPair::operator=(
  77. ValueDestructorPair&& value_destructor_pair) {
  78. // Destroy |value_| before overwriting it with a new value.
  79. if (value_)
  80. destructor_(value_);
  81. value_ = value_destructor_pair.value_;
  82. destructor_ = value_destructor_pair.destructor_;
  83. value_destructor_pair.value_ = nullptr;
  84. return *this;
  85. }
  86. } // namespace internal
  87. } // namespace base