diff options
author | Christopher Faylor <me@cgf.cx> | 2010-02-02 02:00:01 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2010-02-02 02:00:01 +0000 |
commit | fc6a0dc849d07c3aace5e06fa6eee01b45e83d68 (patch) | |
tree | dac1dd4b9a2ec218156b50c57db3753c58c81413 /winsup/cygwin/dll_init.cc | |
parent | a3906150100103ab8e268f9ad0785fca83341e9f (diff) | |
download | newlib-fc6a0dc849d07c3aace5e06fa6eee01b45e83d68.zip newlib-fc6a0dc849d07c3aace5e06fa6eee01b45e83d68.tar.gz newlib-fc6a0dc849d07c3aace5e06fa6eee01b45e83d68.tar.bz2 |
* dcrt0.cc (atexit_lock): Delete.
(cygwin_exit): Remove atexit lock.
(cygwin_atexit): Ditto. Rename parameter to match newlib. Call __cxa_atexit
when invoked by a registered DLL.
* dll_init.cc (remove_dll_atexit): Delete.
(dll_list::find): New function.
(dll_list::detach): Use dll_list::find to find dll associated with return
address. Use __cxa_finalize to run atexit functions associated with the dll.
(cygwin_detach_dll): Don't assume that HANDLE == void *.
* dll_init.h (dll_list::find): Declare.
(__cxa_atexit): Ditto.
(__cxa_finalize): Ditto.
* init.cc (dll_entry): Clarify comment.
Diffstat (limited to 'winsup/cygwin/dll_init.cc')
-rw-r--r-- | winsup/cygwin/dll_init.cc | 80 |
1 files changed, 30 insertions, 50 deletions
diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc index 763964b..e449f77 100644 --- a/winsup/cygwin/dll_init.cc +++ b/winsup/cygwin/dll_init.cc @@ -143,63 +143,43 @@ dll_list::alloc (HINSTANCE h, per_process *p, dll_type type) return d; } -/* This function looks for every atexit function registered in the - about-to-be-unloaded DLL and runs it. - - newlib does not provide any method for selectively running elements - from the atexit() queue so we have to roll our own. - - Note that this is not foolproof since a function in the DLL could - register an atexit function outside of the DLL and that should be - run when the DLL detachs. */ -static void -remove_dll_atexit (MEMORY_BASIC_INFORMATION& m) +dll * +dll_list::find (void *retaddr) { - unsigned char *dll_beg = (unsigned char *) m.AllocationBase; - unsigned char *dll_end = (unsigned char *) m.AllocationBase + m.RegionSize; - struct _atexit *p = _GLOBAL_REENT->_atexit; - for (int n = p->_ind - 1; n >= 0; n--) - { - void (*fn) (void) = p->_fns[n]; - if ((unsigned char *) fn >= dll_beg && (unsigned char *) fn < dll_end) - { - fn (); - p->_fns[n] = NULL; - } - } + MEMORY_BASIC_INFORMATION m; + if (!VirtualQuery (retaddr, &m, sizeof m)) + return NULL; + HMODULE h = (HMODULE) m.AllocationBase; + + dll *d = &start; + while ((d = d->next)) + if (d->handle == h) + break; + return d; } /* Detach a DLL from the chain. */ void dll_list::detach (void *retaddr) { - if (!myself || exit_state) - return; - MEMORY_BASIC_INFORMATION m; - if (!VirtualQuery (retaddr, &m, sizeof m)) + dll *d; + if (!myself || exit_state || !(d = find (retaddr))) return; - HMODULE h = (HMODULE) m.AllocationBase; - - dll *d = &start; - while ((d = d->next)) - if (d->handle != h) - continue; - else if (d->count <= 0) - system_printf ("WARNING: trying to detach an already detached dll ..."); - else if (--d->count == 0) - { - remove_dll_atexit (m); - d->run_dtors (); - d->prev->next = d->next; - if (d->next) - d->next->prev = d->prev; - if (d->type == DLL_LOAD) - loaded_dlls--; - if (end == d) - end = d->prev; - cfree (d); - break; - } + if (d->count <= 0) + system_printf ("WARNING: trying to detach an already detached dll ..."); + if (--d->count == 0) + { + __cxa_finalize (d); + d->run_dtors (); + d->prev->next = d->next; + if (d->next) + d->next->prev = d->prev; + if (d->type == DLL_LOAD) + loaded_dlls--; + if (end == d) + end = d->prev; + cfree (d); + } } /* Initialization for all linked DLLs, called by dll_crt0_1. */ @@ -427,7 +407,7 @@ cygwin_detach_dll (dll *) { HANDLE retaddr; if (_my_tls.isinitialized ()) - retaddr = (HANDLE) _my_tls.retaddr (); + retaddr = (void *) _my_tls.retaddr (); else retaddr = __builtin_return_address (0); dlls.detach (retaddr); |