MongoDB C++ Driver legacy-1.1.2
Loading...
Searching...
No Matches
threadlocal.h
1#pragma once
2
3/* Copyright 2014 MongoDB Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
19#include <boost/thread/tss.hpp>
21
22
23namespace mongo {
24
25/* thread local "value" rather than a pointer
26 good for things which have copy constructors (and the copy constructor is fast enough)
27 e.g.
28 ThreadLocalValue<int> myint;
29*/
30template <class T>
32public:
33 ThreadLocalValue(T def = 0) : _default(def) {}
34
35 T get() const {
36 T* val = _val.get();
37 if (val)
38 return *val;
39 return _default;
40 }
41
42 void set(const T& i) {
43 T* v = _val.get();
44 if (v) {
45 *v = i;
46 return;
47 }
48 v = new T(i);
49 _val.reset(v);
50 }
51
52 T& getRef() {
53 T* v = _val.get();
54 if (v) {
55 return *v;
56 }
57 v = new T(_default);
58 _val.reset(v);
59 return *v;
60 }
61
62private:
63 boost::thread_specific_ptr<T> _val;
64 const T _default;
65};
66
67/* TSP
68 These macros use intrinsics which are faster than boost::thread_specific_ptr.
69 However the intrinsics don't free up objects on thread closure. Thus we use
70 a combination here, with the assumption that reset's are infrequent, so that
71 get's are fast.
72*/
73#if defined(MONGO_HAVE___THREAD) || defined(MONGO_HAVE___DECLSPEC_THREAD)
74
75template <class T>
76struct TSP {
77 boost::thread_specific_ptr<T> tsp;
78
79public:
80 T* get() const;
81 void reset(T* v);
82 T* getMake() {
83 T* t = get();
84 if (t == 0)
85 reset(t = new T());
86 return t;
87 }
88};
89
90#if defined(MONGO_HAVE___DECLSPEC_THREAD)
91
92#define TSP_DECLARE(T, p) extern TSP<T> p;
93
94#define TSP_DEFINE(T, p) \
95 __declspec(thread) T* _##p; \
96 TSP<T> p; \
97 template <> \
98 T* TSP<T>::get() const { \
99 return _##p; \
100 } \
101 void TSP<T>::reset(T* v) { \
102 tsp.reset(v); \
103 _##p = v; \
104 }
105#else
106
107#define TSP_DECLARE(T, p) \
108 extern __thread T* _##p; \
109 template <> \
110 inline T* TSP<T>::get() const { \
111 return _##p; \
112 } \
113 extern TSP<T> p;
114
115#define TSP_DEFINE(T, p) \
116 __thread T* _##p; \
117 template <> \
118 void TSP<T>::reset(T* v) { \
119 tsp.reset(v); \
120 _##p = v; \
121 } \
122 TSP<T> p;
123#endif
124
125#elif defined(_POSIX_THREADS) && (_POSIX_THREADS >= 0)
126template <class T>
127struct TSP {
128 pthread_key_t _key;
129
130public:
131 TSP() {
132 verify(pthread_key_create(&_key, TSP::dodelete) == 0);
133 }
134
135 ~TSP() {
136 pthread_key_delete(_key);
137 }
138
139 static void dodelete(void* x) {
140 T* t = reinterpret_cast<T*>(x);
141 delete t;
142 }
143
144 T* get() const {
145 return reinterpret_cast<T*>(pthread_getspecific(_key));
146 }
147
148 void reset(T* v) {
149 T* old = get();
150 delete old;
151 verify(pthread_setspecific(_key, v) == 0);
152 }
153
154 T* getMake() {
155 T* t = get();
156 if (t == 0) {
157 t = new T();
158 reset(t);
159 }
160 return t;
161 }
162};
163
164#define TSP_DECLARE(T, p) extern TSP<T> p;
165
166#define TSP_DEFINE(T, p) TSP<T> p;
167
168#else
169
170template <class T>
171struct TSP {
172 boost::thread_specific_ptr<T> tsp;
173
174public:
175 T* get() const {
176 return tsp.get();
177 }
178 void reset(T* v) {
179 tsp.reset(v);
180 }
181 T* getMake() {
182 T* t = get();
183 if (t == 0)
184 reset(t = new T());
185 return t;
186 }
187};
188
189#define TSP_DECLARE(T, p) extern TSP<T> p;
190
191#define TSP_DEFINE(T, p) TSP<T> p;
192
193#endif
194}
Definition threadlocal.h:31
Utility functions for parsing numbers from strings.
Definition compare_numbers.h:20
macros for mongo internals
Definition threadlocal.h:171
remove mongo implementation macros after using