X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/8b73c5318ccc837aff38c0e5a824bc4fd56c75c8..7344108e8a129a3f9b4df5ab0f98a1713db03b89:/include/wx/tls.h diff --git a/include/wx/tls.h b/include/wx/tls.h index 1902716068..6886434c00 100644 --- a/include/wx/tls.h +++ b/include/wx/tls.h @@ -22,10 +22,13 @@ #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 @@ -33,7 +36,8 @@ #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() @@ -44,8 +48,16 @@ #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" #elif defined(__UNIX__) #include "wx/unix/tls.h" #else @@ -58,6 +70,14 @@ // wxTlsValue 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 is destroyed. The only exception to this is the + // value for the main thread, which is always freed when + // wxTlsValue is destroyed. template class wxTlsValue { @@ -65,32 +85,17 @@ 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() -#ifdef __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 @@ -131,7 +136,7 @@ }; #define wxTLS_TYPE(T) wxTlsValue - #define wxTLS_PTR(var) (var) + #define wxTLS_PTR(var) ((var).Get()) #define wxTLS_VALUE(var) (*(var)) #endif // wxHAS_COMPILER_TLS/!wxHAS_COMPILER_TLS