summaryrefslogtreecommitdiffstats
path: root/gcc48-libstdc-atexit_thread.patch
diff options
context:
space:
mode:
Diffstat (limited to 'gcc48-libstdc-atexit_thread.patch')
-rw-r--r--gcc48-libstdc-atexit_thread.patch83
1 files changed, 83 insertions, 0 deletions
diff --git a/gcc48-libstdc-atexit_thread.patch b/gcc48-libstdc-atexit_thread.patch
new file mode 100644
index 0000000..1ae7e09
--- /dev/null
+++ b/gcc48-libstdc-atexit_thread.patch
@@ -0,0 +1,83 @@
+Index: libstdc++-v3/config/os/mingw32-w64/os_defines.h
+===================================================================
+--- libstdc++-v3/config/os/mingw32-w64/os_defines.h (revision 213759)
++++ libstdc++-v3/config/os/mingw32-w64/os_defines.h (working copy)
+@@ -78,4 +78,9 @@
+ #define _GLIBCXX_LLP64 1
+ #endif
+
++// Enable use of GetModuleHandleEx (requires Windows XP/2003) in
++// __cxa_thread_atexit to prevent modules from being unloaded before
++// their dtors are called
++#define _GLIBCXX_THREAD_ATEXIT_WIN32 1
++
+ #endif
+Index: libstdc++-v3/config/os/newlib/os_defines.h
+===================================================================
+--- libstdc++-v3/config/os/newlib/os_defines.h (revision 213759)
++++ libstdc++-v3/config/os/newlib/os_defines.h (working copy)
+@@ -47,6 +47,12 @@
+
+ // See libstdc++/20806.
+ #define _GLIBCXX_HAVE_DOS_BASED_FILESYSTEM 1
++
++// Enable use of GetModuleHandleEx (requires Windows XP/2003) in
++// __cxa_thread_atexit to prevent modules from being unloaded before
++// their dtors are called
++#define _GLIBCXX_THREAD_ATEXIT_WIN32 1
++
+ #endif
+
+ #endif
+Index: libstdc++-v3/libsupc++/atexit_thread.cc
+===================================================================
+--- libstdc++-v3/libsupc++/atexit_thread.cc (revision 213759)
++++ libstdc++-v3/libsupc++/atexit_thread.cc (working copy)
+@@ -25,6 +25,10 @@
+ #include <cstdlib>
+ #include <new>
+ #include "bits/gthr.h"
++#ifdef _GLIBCXX_THREAD_ATEXIT_WIN32
++#define WIN32_LEAN_AND_MEAN
++#include <windows.h>
++#endif
+
+ #if HAVE___CXA_THREAD_ATEXIT_IMPL
+
+@@ -47,6 +51,9 @@
+ void (*destructor)(void *);
+ void *object;
+ elt *next;
++#ifdef _GLIBCXX_THREAD_ATEXIT_WIN32
++ HMODULE dll;
++#endif
+ };
+
+ // Keep a per-thread list of cleanups in gthread_key storage.
+@@ -62,6 +69,11 @@
+ {
+ elt *old_e = e;
+ e->destructor (e->object);
++#ifdef _GLIBCXX_THREAD_ATEXIT_WIN32
++ /* Decrement DLL count */
++ if (e->dll)
++ FreeLibrary (e->dll);
++#endif
+ e = e->next;
+ delete (old_e);
+ }
+@@ -133,6 +145,14 @@
+ new_elt->destructor = dtor;
+ new_elt->object = obj;
+ new_elt->next = first;
++#ifdef _GLIBCXX_THREAD_ATEXIT_WIN32
++ /* Store the DLL address for a later call to FreeLibrary in new_elt and
++ increment DLL load count. This blocks the unloading of the DLL
++ before the thread-local dtors have been called. This does NOT help
++ if FreeLibrary/dlclose is called in excess. */
++ GetModuleHandleExW (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
++ (LPCWSTR) dtor, &new_elt->dll);
++#endif
+
+ if (__gthread_active_p ())
+ __gthread_setspecific (key, new_elt);