]>
git.saurik.com Git - wxWidgets.git/blob - include/wx/tls.h
1 ///////////////////////////////////////////////////////////////////////////////
3 // Purpose: Implementation of thread local storage
4 // Author: Vadim Zeitlin
7 // Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
16 // ----------------------------------------------------------------------------
17 // check for compiler support of thread-specific variables
18 // ----------------------------------------------------------------------------
20 // when not using threads at all, there is no need for thread-specific
21 // values to be really thread-specific
23 #define wxHAS_COMPILER_TLS
24 #define wxTHREAD_SPECIFIC_DECL
25 // __thread keyword is not supported correctly by MinGW, at least in some
26 // configurations, see http://sourceforge.net/support/tracker.php?aid=2837047
27 // and when in doubt we prefer to not use it at all.
28 #elif defined(HAVE___THREAD_KEYWORD) && !defined(__MINGW32__)
29 #define wxHAS_COMPILER_TLS
30 #define wxTHREAD_SPECIFIC_DECL __thread
31 // MSVC has its own version which might be supported by some other Windows
32 // compilers, to be tested
33 #elif wxCHECK_VISUALC_VERSION(7)
34 #define wxHAS_COMPILER_TLS
35 #define wxTHREAD_SPECIFIC_DECL __declspec(thread)
38 // ----------------------------------------------------------------------------
39 // define wxTLS_TYPE()
40 // ----------------------------------------------------------------------------
42 #ifdef wxHAS_COMPILER_TLS
43 #define wxTLS_TYPE(T) wxTHREAD_SPECIFIC_DECL T
44 #define wxTLS_PTR(var) (&(var))
45 #define wxTLS_VALUE(var) (var)
46 #else // !wxHAS_COMPILER_TLS
50 typedef void (*wxTlsDestructorFunction
)(void*);
53 #if defined(__WINDOWS__)
54 #include "wx/msw/tls.h"
55 #elif defined(__OS2__)
56 #include "wx/os2/tls.h"
57 #elif defined(__UNIX__)
58 #include "wx/unix/tls.h"
60 // TODO: we could emulate TLS for such platforms...
61 #error Neither compiler nor OS support thread-specific variables.
64 #include <stdlib.h> // for calloc()
66 // wxTlsValue<T> represents a thread-specific value of type T but, unlike
67 // with native compiler thread-specific variables, it behaves like a
68 // (never NULL) pointer to T and so needs to be dereferenced before use
70 // Note: T must be a POD!
72 // Note: On Unix, thread-specific T value is freed when the thread exits.
73 // On Windows, thread-specific values are freed later, when given
74 // wxTlsValue<T> is destroyed. The only exception to this is the
75 // value for the main thread, which is always freed when
76 // wxTlsValue<T> is destroyed.
83 // ctor doesn't do anything, the object is created on first access
84 wxTlsValue() : m_key(free
) {}
86 // dtor is only called in the main thread context and so is not enough
87 // to free memory allocated by us for the other threads, we use
88 // destructor function when using Pthreads for this (which is not
89 // called for the main thread as it doesn't call pthread_exit() but
90 // just to be safe we also reset the key anyhow)
94 m_key
.Set(NULL
); // this deletes the value
97 // access the object creating it on demand
100 void *value
= m_key
.Get();
103 // ValueType must be POD to be used in wxHAS_COMPILER_TLS case
104 // anyhow (at least gcc doesn't accept non-POD values being
105 // declared with __thread) so initialize it as a POD too
106 value
= calloc(1, sizeof(ValueType
));
108 if ( !m_key
.Set(value
) )
112 // this will probably result in a crash in the caller but
113 // it's arguably better to crash immediately instead of
114 // slowly dying from out-of-memory errors which would
115 // happen as the next access to this object would allocate
116 // another ValueType instance and so on forever
121 return static_cast<ValueType
*>(value
);
124 // pointer-like accessors
125 ValueType
*operator->() { return Get(); }
126 ValueType
& operator*() { return *Get(); }
131 DECLARE_NO_COPY_TEMPLATE_CLASS(wxTlsValue
, T
)
134 #define wxTLS_TYPE(T) wxTlsValue<T>
135 #define wxTLS_PTR(var) ((var).Get())
136 #define wxTLS_VALUE(var) (*(var))
137 #endif // wxHAS_COMPILER_TLS/!wxHAS_COMPILER_TLS