diff options
author | ktietz <ktietz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-08-19 15:25:12 +0000 |
---|---|---|
committer | ktietz <ktietz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-08-19 15:25:12 +0000 |
commit | 39a4a453059d2f49fab18e9b2a788789ecd4f2e0 (patch) | |
tree | 4ebc6dcde228f02fbdfffc3c62c33700b0653771 /libstdc++-v3/libsupc++ | |
parent | 1db4f54b5b0d78f8de678c099c6bd117ff95d82f (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.cc | 20 |
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); |