* dll_init.cc (remove_dll_atexit): New function.
(dll_list::detach): Run any atexit handlers registered in the DLL prior to unloading.
This commit is contained in:
parent
2b37c431b1
commit
d5c4cd3f6c
@ -1,3 +1,9 @@
|
|||||||
|
2010-01-29 Christopher Faylor <me+cygwin@cgf.cx>
|
||||||
|
|
||||||
|
* dll_init.cc (remove_dll_atexit): New function.
|
||||||
|
(dll_list::detach): Run any atexit handlers registered in the DLL prior
|
||||||
|
to unloading.
|
||||||
|
|
||||||
2010-01-29 Christopher Faylor <me+cygwin@cgf.cx>
|
2010-01-29 Christopher Faylor <me+cygwin@cgf.cx>
|
||||||
|
|
||||||
* libc/strfmon.c (__setup_vars): Fix compiler warning about assigning
|
* libc/strfmon.c (__setup_vars): Fix compiler warning about assigning
|
||||||
|
@ -20,6 +20,7 @@ details. */
|
|||||||
#include "pinfo.h"
|
#include "pinfo.h"
|
||||||
#include "cygtls.h"
|
#include "cygtls.h"
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
#include <sys/reent.h>
|
||||||
|
|
||||||
extern void __stdcall check_sanity_and_sync (per_process *);
|
extern void __stdcall check_sanity_and_sync (per_process *);
|
||||||
|
|
||||||
@ -142,6 +143,32 @@ dll_list::alloc (HINSTANCE h, per_process *p, dll_type type)
|
|||||||
return d;
|
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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Detach a DLL from the chain. */
|
/* Detach a DLL from the chain. */
|
||||||
void
|
void
|
||||||
dll_list::detach (void *retaddr)
|
dll_list::detach (void *retaddr)
|
||||||
@ -161,6 +188,7 @@ dll_list::detach (void *retaddr)
|
|||||||
system_printf ("WARNING: trying to detach an already detached dll ...");
|
system_printf ("WARNING: trying to detach an already detached dll ...");
|
||||||
else if (--d->count == 0)
|
else if (--d->count == 0)
|
||||||
{
|
{
|
||||||
|
remove_dll_atexit (m);
|
||||||
d->run_dtors ();
|
d->run_dtors ();
|
||||||
d->prev->next = d->next;
|
d->prev->next = d->next;
|
||||||
if (d->next)
|
if (d->next)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user