MongoDB C++ Driver  legacy-1.1.2
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 
23 namespace 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 */
30 template <class T>
32 public:
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 
62 private:
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 
75 template <class T>
76 struct TSP {
77  boost::thread_specific_ptr<T> tsp;
78 
79 public:
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)
126 template <class T>
127 struct TSP {
128  pthread_key_t _key;
129 
130 public:
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 
170 template <class T>
171 struct TSP {
172  boost::thread_specific_ptr<T> tsp;
173 
174 public:
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 }
Utility functions for parsing numbers from strings.
Definition: compare_numbers.h:20
remove mongo implementation macros after using
macros for mongo internals
Definition: threadlocal.h:31
Definition: threadlocal.h:171