|  | // 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. | 
|  |  | 
|  | #ifndef BASE_THREADING_SEQUENCE_LOCAL_STORAGE_MAP_H_ | 
|  | #define BASE_THREADING_SEQUENCE_LOCAL_STORAGE_MAP_H_ | 
|  |  | 
|  | #include "base/base_export.h" | 
|  | #include "base/containers/flat_map.h" | 
|  | #include "base/macros.h" | 
|  |  | 
|  | namespace base { | 
|  | namespace internal { | 
|  |  | 
|  | // A SequenceLocalStorageMap holds (slot_id) -> (value, destructor) items for a | 
|  | // sequence. When a task runs, it is expected that a pointer to its sequence's | 
|  | // SequenceLocalStorageMap is set in TLS using | 
|  | // ScopedSetSequenceMapLocalStorageForCurrentThread. When a | 
|  | // SequenceLocalStorageMap is destroyed, it invokes the destructors associated | 
|  | // with values stored within it. | 
|  | // The Get() and Set() methods should not be accessed directly. | 
|  | // Use SequenceLocalStorageSlot to Get() and Set() values in the current | 
|  | // sequence's SequenceLocalStorageMap. | 
|  | class BASE_EXPORT SequenceLocalStorageMap { | 
|  | public: | 
|  | SequenceLocalStorageMap(); | 
|  | ~SequenceLocalStorageMap(); | 
|  |  | 
|  | // Returns the SequenceLocalStorage bound to the current thread. It is invalid | 
|  | // to call this outside the scope of a | 
|  | // ScopedSetSequenceLocalStorageForCurrentThread. | 
|  | static SequenceLocalStorageMap& GetForCurrentThread(); | 
|  |  | 
|  | // Holds a pointer to a value alongside a destructor for this pointer. | 
|  | // Calls the destructor on the value upon destruction. | 
|  | class BASE_EXPORT ValueDestructorPair { | 
|  | public: | 
|  | using DestructorFunc = void(void*); | 
|  |  | 
|  | ValueDestructorPair(void* value, DestructorFunc* destructor); | 
|  | ~ValueDestructorPair(); | 
|  |  | 
|  | ValueDestructorPair(ValueDestructorPair&& value_destructor_pair); | 
|  |  | 
|  | ValueDestructorPair& operator=(ValueDestructorPair&& value_destructor_pair); | 
|  |  | 
|  | void* value() const { return value_; } | 
|  |  | 
|  | private: | 
|  | void* value_; | 
|  | DestructorFunc* destructor_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(ValueDestructorPair); | 
|  | }; | 
|  |  | 
|  | // Returns the value stored in |slot_id| or nullptr if no value was stored. | 
|  | void* Get(int slot_id); | 
|  |  | 
|  | // Stores |value_destructor_pair| in |slot_id|. Overwrites and destroys any | 
|  | // previously stored value. | 
|  | void Set(int slot_id, ValueDestructorPair value_destructor_pair); | 
|  |  | 
|  | private: | 
|  | // Map from slot id to ValueDestructorPair. | 
|  | // flat_map was chosen because there are expected to be relatively few entries | 
|  | // in the map. For low number of entries, flat_map is known to perform better | 
|  | // than other map implementations. | 
|  | base::flat_map<int, ValueDestructorPair> sls_map_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(SequenceLocalStorageMap); | 
|  | }; | 
|  |  | 
|  | // Within the scope of this object, | 
|  | // SequenceLocalStorageMap::GetForCurrentThread() will return a reference to the | 
|  | // SequenceLocalStorageMap object passed to the constructor. There can be only | 
|  | // one ScopedSetSequenceLocalStorageMapForCurrentThread instance per scope. | 
|  | class BASE_EXPORT ScopedSetSequenceLocalStorageMapForCurrentThread { | 
|  | public: | 
|  | ScopedSetSequenceLocalStorageMapForCurrentThread( | 
|  | SequenceLocalStorageMap* sequence_local_storage); | 
|  |  | 
|  | ~ScopedSetSequenceLocalStorageMapForCurrentThread(); | 
|  |  | 
|  | private: | 
|  | DISALLOW_COPY_AND_ASSIGN(ScopedSetSequenceLocalStorageMapForCurrentThread); | 
|  | }; | 
|  | }  // namespace internal | 
|  | }  // namespace base | 
|  |  | 
|  | #endif  // BASE_THREADING_SEQUENCE_LOCAL_STORAGE_MAP_H_ |