MongoDB C++ Driver legacy-1.0.1
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 */
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 public:
79 T* get() const;
80 void reset(T* v);
81 T* getMake() {
82 T *t = get();
83 if( t == 0 )
84 reset( t = new T() );
85 return t;
86 }
87 };
88
89# if defined(MONGO_HAVE___DECLSPEC_THREAD)
90
91# define TSP_DECLARE(T,p) extern TSP<T> p;
92
93# define TSP_DEFINE(T,p) __declspec( thread ) T* _ ## p; \
94 TSP<T> p; \
95 template<> T* TSP<T>::get() const { return _ ## p; } \
96 void TSP<T>::reset(T* v) { \
97 tsp.reset(v); \
98 _ ## p = v; \
99 }
100# else
101
102# define TSP_DECLARE(T,p) \
103 extern __thread T* _ ## p; \
104 template<> inline T* TSP<T>::get() const { return _ ## p; } \
105 extern TSP<T> p;
106
107# define TSP_DEFINE(T,p) \
108 __thread T* _ ## p; \
109 template<> void TSP<T>::reset(T* v) { \
110 tsp.reset(v); \
111 _ ## p = v; \
112 } \
113 TSP<T> p;
114# endif
115
116#elif defined(_POSIX_THREADS) && (_POSIX_THREADS >= 0)
117 template< class T>
118 struct TSP {
119 pthread_key_t _key;
120 public:
121 TSP() {
122 verify( pthread_key_create( &_key, TSP::dodelete ) == 0 );
123 }
124
125 ~TSP() {
126 pthread_key_delete( _key );
127 }
128
129 static void dodelete( void* x ) {
130 T* t = reinterpret_cast<T*>(x);
131 delete t;
132 }
133
134 T* get() const {
135 return reinterpret_cast<T*>( pthread_getspecific( _key ) );
136 }
137
138 void reset(T* v) {
139 T* old = get();
140 delete old;
141 verify( pthread_setspecific( _key, v ) == 0 );
142 }
143
144 T* getMake() {
145 T *t = get();
146 if( t == 0 ) {
147 t = new T();
148 reset( t );
149 }
150 return t;
151 }
152 };
153
154# define TSP_DECLARE(T,p) extern TSP<T> p;
155
156# define TSP_DEFINE(T,p) TSP<T> p;
157
158#else
159
160 template< class T >
161 struct TSP {
162 boost::thread_specific_ptr<T> tsp;
163 public:
164 T* get() const { return tsp.get(); }
165 void reset(T* v) { tsp.reset(v); }
166 T* getMake() {
167 T *t = get();
168 if( t == 0 )
169 reset( t = new T() );
170 return t;
171 }
172 };
173
174# define TSP_DECLARE(T,p) extern TSP<T> p;
175
176# define TSP_DEFINE(T,p) TSP<T> p;
177
178#endif
179
180}
Definition threadlocal.h:31
the main MongoDB namespace
Definition bulk_operation_builder.h:24
macros for mongo internals
Definition threadlocal.h:161
remove mongo implementation macros after using