blob: 8b9155c5b23eeef1dd28ef67dad9bb3aab3d95dd [file] [log] [blame]
Jeffrey He108d296c2017-06-12 16:07:351// 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
12namespace base {
13namespace 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.
Jeffrey He74d41be2017-06-12 20:34:1321// 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.
Jeffrey He108d296c2017-06-12 16:07:3524class 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
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,
Francois Dorayc4c3f642017-08-04 14:56:2274// 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.
Jeffrey He108d296c2017-06-12 16:07:3577class BASE_EXPORT ScopedSetSequenceLocalStorageMapForCurrentThread {
78 public:
79 ScopedSetSequenceLocalStorageMapForCurrentThread(
80 SequenceLocalStorageMap* sequence_local_storage);
81
82 ~ScopedSetSequenceLocalStorageMapForCurrentThread();
83
84 private:
Jeffrey He108d296c2017-06-12 16:07:3585 DISALLOW_COPY_AND_ASSIGN(ScopedSetSequenceLocalStorageMapForCurrentThread);
86};
87} // namespace internal
88} // namespace base
89
90#endif // BASE_THREADING_SEQUENCE_LOCAL_STORAGE_MAP_H_