aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/libsupc++
diff options
context:
space:
mode:
authorktietz <ktietz@138bc75d-0d04-0410-961f-82ee72b054a4>2014-08-19 15:25:12 +0000
committerktietz <ktietz@138bc75d-0d04-0410-961f-82ee72b054a4>2014-08-19 15:25:12 +0000
commit39a4a453059d2f49fab18e9b2a788789ecd4f2e0 (patch)
tree4ebc6dcde228f02fbdfffc3c62c33700b0653771 /libstdc++-v3/libsupc++
parent1db4f54b5b0d78f8de678c099c6bd117ff95d82f (diff)
2014-08-19 Yaakov Selkowitz <yselkowi@redhat.com>
Kai Tietz <ktietz@redhat.com> * config/os/mingw32-w64/os_defines.h (_GLIBCXX_THREAD_ATEXIT_WIN32): Define. * config/os/newlib/os_defines.h (_GLIBCXX_THREAD_ATEXIT_WIN32): Ditto. * libsupc++/atexit_thread.cc [_GLIBCXX_THREAD_ATEXIT_WIN32]: #include <windows.h>. (struct elt): Add dll member. (run): Decrement dll refcount. (__cxxabiv1::__cxa_thread_atexit): Increment dll refcount. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@214163 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/libsupc++')
-rw-r--r--libstdc++-v3/libsupc++/atexit_thread.cc20
1 files changed, 20 insertions, 0 deletions
diff --git a/libstdc++-v3/libsupc++/atexit_thread.cc b/libstdc++-v3/libsupc++/atexit_thread.cc
index dff08e92477..d7d84d2c626 100644
--- a/libstdc++-v3/libsupc++/atexit_thread.cc
+++ b/libstdc++-v3/libsupc++/atexit_thread.cc
@@ -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 _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL
@@ -47,6 +51,9 @@ namespace {
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 @@ namespace {
{
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 @@ __cxxabiv1::__cxa_thread_atexit (void (*dtor)(void *), void *obj, void */*dso_ha
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);