#if !wxUSE_THREADS
#define wxHAS_COMPILER_TLS
#define wxTHREAD_SPECIFIC_DECL
-// __thread keyword is supported if configure detected it or when using mingw32
-// >= 4.3 which is known to have it too
-#elif defined(HAVE___THREAD_KEYWORD) || \
- (defined(__MINGW32__) && wxCHECK_GCC_VERSION(4, 3))
+// otherwise try to find the compiler-specific way to handle TLS unless
+// explicitly disabled by setting wxUSE_COMPILER_TLS to 0 (it is 1 by default).
+#elif wxUSE_COMPILER_TLS
+// __thread keyword is not supported correctly by MinGW, at least in some
+// configurations, see http://sourceforge.net/support/tracker.php?aid=2837047
+// and when in doubt we prefer to not use it at all.
+#if defined(HAVE___THREAD_KEYWORD) && !defined(__MINGW32__)
#define wxHAS_COMPILER_TLS
#define wxTHREAD_SPECIFIC_DECL __thread
// MSVC has its own version which might be supported by some other Windows
#elif wxCHECK_VISUALC_VERSION(7)
#define wxHAS_COMPILER_TLS
#define wxTHREAD_SPECIFIC_DECL __declspec(thread)
-#endif
+#endif // compilers
+#endif // wxUSE_COMPILER_TLS
// ----------------------------------------------------------------------------
// define wxTLS_TYPE()
#define wxTLS_PTR(var) (&(var))
#define wxTLS_VALUE(var) (var)
#else // !wxHAS_COMPILER_TLS
- #ifdef __WXMSW__
+
+ extern "C"
+ {
+ typedef void (*wxTlsDestructorFunction)(void*);
+ }
+
+ #if defined(__WINDOWS__)
#include "wx/msw/tls.h"
#elif defined(__OS2__)
#include "wx/os2/tls.h"
// wxTlsValue<T> represents a thread-specific value of type T but, unlike
// with native compiler thread-specific variables, it behaves like a
// (never NULL) pointer to T and so needs to be dereferenced before use
+ //
+ // Note: T must be a POD!
+ //
+ // Note: On Unix, thread-specific T value is freed when the thread exits.
+ // On Windows, thread-specific values are freed later, when given
+ // wxTlsValue<T> is destroyed. The only exception to this is the
+ // value for the main thread, which is always freed when
+ // wxTlsValue<T> is destroyed.
template <typename T>
class wxTlsValue
{
typedef T ValueType;
// ctor doesn't do anything, the object is created on first access
- //
- // FIXME: the thread-specific values are currently not freed under
- // Windows, resulting in memory leaks, this must be implemented
- // there somehow (probably by keeping a list of all TLS objects
- // and cleaning them up in wxThread cleanup)
- wxTlsValue()
-#if !defined(__OS2__) && defined(__UNIX__)
- : m_key(free)
-#endif
- {
- }
+ wxTlsValue() : m_key(free) {}
// dtor is only called in the main thread context and so is not enough
// to free memory allocated by us for the other threads, we use
// destructor function when using Pthreads for this (which is not
// called for the main thread as it doesn't call pthread_exit() but
- // just to be safe we also reset the key anyhow) and simply leak the
- // memory under Windows (see the FIXME above)
+ // just to be safe we also reset the key anyhow)
~wxTlsValue()
{
- void * const value = m_key.Get();
- if ( value)
- {
- free(value);
- m_key.Set(NULL);
- }
+ if ( m_key.Get() )
+ m_key.Set(NULL); // this deletes the value
}
// access the object creating it on demand
};
#define wxTLS_TYPE(T) wxTlsValue<T>
- #define wxTLS_PTR(var) (var)
+ #define wxTLS_PTR(var) ((var).Get())
#define wxTLS_VALUE(var) (*(var))
#endif // wxHAS_COMPILER_TLS/!wxHAS_COMPILER_TLS