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 
5 #ifndef BASE_THREADING_SEQUENCE_LOCAL_STORAGE_MAP_H_
6 #define BASE_THREADING_SEQUENCE_LOCAL_STORAGE_MAP_H_
7 
8 #include "base/base_export.h"
9 #include "base/containers/flat_map.h"
10 #include "base/macros.h"
11 
12 namespace base {
13 namespace internal {
14 
15 // A SequenceLocalStorageMap holds (slot_id) -> (value, destructor) items for a
16 // sequence. When a task runs, it is expected that a pointer to its sequence's
17 // SequenceLocalStorageMap is set in TLS using
18 // ScopedSetSequenceMapLocalStorageForCurrentThread. When a
19 // SequenceLocalStorageMap is destroyed, it invokes the destructors associated
20 // with values stored within it.
21 // The Get() and Set() methods should not be accessed directly.
22 // Use SequenceLocalStorageSlot to Get() and Set() values in the current
23 // sequence's SequenceLocalStorageMap.
24 class BASE_EXPORT SequenceLocalStorageMap {
25  public:
26   SequenceLocalStorageMap();
27   ~SequenceLocalStorageMap();
28 
29   // Returns the SequenceLocalStorage bound to the current thread. It is invalid
30   // to call this outside the scope of a
31   // ScopedSetSequenceLocalStorageForCurrentThread.
32   static SequenceLocalStorageMap& GetForCurrentThread();
33 
34   // Holds a pointer to a value alongside a destructor for this pointer.
35   // Calls the destructor on the value upon destruction.
36   class BASE_EXPORT ValueDestructorPair {
37    public:
38     using DestructorFunc = void(void*);
39 
40     ValueDestructorPair(void* value, DestructorFunc* destructor);
41     ~ValueDestructorPair();
42 
43     ValueDestructorPair(ValueDestructorPair&& value_destructor_pair);
44 
45     ValueDestructorPair& operator=(ValueDestructorPair&& value_destructor_pair);
46 
value()47     void* value() const { return value_; }
48 
49    private:
50     void* value_;
51     DestructorFunc* destructor_;
52 
53     DISALLOW_COPY_AND_ASSIGN(ValueDestructorPair);
54   };
55 
56   // Returns the value stored in |slot_id| or nullptr if no value was stored.
57   void* Get(int slot_id);
58 
59   // Stores |value_destructor_pair| in |slot_id|. Overwrites and destroys any
60   // previously stored value.
61   void Set(int slot_id, ValueDestructorPair value_destructor_pair);
62 
63  private:
64   // Map from slot id to ValueDestructorPair.
65   // flat_map was chosen because there are expected to be relatively few entries
66   // in the map. For low number of entries, flat_map is known to perform better
67   // than other map implementations.
68   base::flat_map<int, ValueDestructorPair> sls_map_;
69 
70   DISALLOW_COPY_AND_ASSIGN(SequenceLocalStorageMap);
71 };
72 
73 // Within the scope of this object,
74 // SequenceLocalStorageMap::GetForCurrentThread() will return a reference to the
75 // SequenceLocalStorageMap object passed to the constructor. There can be only
76 // one ScopedSetSequenceLocalStorageMapForCurrentThread instance per scope.
77 class BASE_EXPORT ScopedSetSequenceLocalStorageMapForCurrentThread {
78  public:
79   ScopedSetSequenceLocalStorageMapForCurrentThread(
80       SequenceLocalStorageMap* sequence_local_storage);
81 
82   ~ScopedSetSequenceLocalStorageMapForCurrentThread();
83 
84  private:
85   DISALLOW_COPY_AND_ASSIGN(ScopedSetSequenceLocalStorageMapForCurrentThread);
86 };
87 }  // namespace internal
88 }  // namespace base
89 
90 #endif  // BASE_THREADING_SEQUENCE_LOCAL_STORAGE_MAP_H_
91