The JSS_THREAD_LOCAL macro
provides emulation for the thread_local
keyword at block scope.
#define JSS_THREAD_LOCAL(type,name,initializer) see below
The block-scope statement
JSS_THREAD_LOCAL(X,foo,(arg1,arg2));
is equivalent to the C++11 statement
thread_local X foo(arg1,arg2);
Both statements declare a variable named foo
of type X which is thread-local:
each thread has its own copy. If X
has a non-trivial destructor then it is called when each thread exits,
in order to destroy that thread's copy of the variable. The expression
&foo
will return a unique address on each thread.
Only parenthesized initializers can be used; aggregate initializers and
copy-initialization cannot be used. Use ()
for a default initialized value, e.g.
JSS_THREAD_LOCAL(std::map<int,int>,m,());
will declare a default-initialized std::map<int,int>
called m which is local
to each thread.
Restrictions
JSS_THREAD_LOCAL cannot
be used to declare variables of reference type. This can be easily worked
around by using a variable of pointer type.
JSS_THREAD_LOCAL can only
be used to declare variables of local type if the compiler supports it.
For gcc, this requires gcc 4.5 or later, and the use of the -std=c++0x flag;
for MSVC this is always enabled.
JSS_THREAD_LOCAL cannot
be used to declare namespace scope variables or static class members. However,
the need for these can be avoided by the use of an accessor function. e.g.
class Z { public: static X& x() { JSS_THREAD_LOCAL(X,local,(initializer)); return local; } void do_stuff() { x().foo(); } };
instead of
class Z { public: static thread_local X x; void do_stuff() { x.foo(); } }; thread_local X Z::x(initializer);
Header
#include <thread>