2010-01-25 Kai Tietz <kai.tietz@onevision.com>
Implement TLS Callback. * tlsmcrt.c: New file. * tlsmthread.c: Ditto. * tlssup.c: Ditto. * tlsthrd.c: Ditto. * Makefile.in: Include new files. * crt1.c: Implement TLS Callback. * dllcrt1.c: Ditto. * mthr_stub.c: Remove.
This commit is contained in:
parent
8944c6af48
commit
d359eb2e1f
|
@ -1,3 +1,16 @@
|
|||
2010-01-25 Kai Tietz <kai.tietz@onevision.com>
|
||||
|
||||
Implement TLS Callback.
|
||||
|
||||
* tlsmcrt.c: New file.
|
||||
* tlsmthread.c: Ditto.
|
||||
* tlssup.c: Ditto.
|
||||
* tlsthrd.c: Ditto.
|
||||
* Makefile.in: Include new files.
|
||||
* crt1.c: Implement TLS Callback.
|
||||
* dllcrt1.c: Ditto.
|
||||
* mthr_stub.c: Remove.
|
||||
|
||||
2009-11-29 Chris Sutcliffe <ir0nh34d@users.sourceforge.net>
|
||||
|
||||
* include/_mingw.h: Increment version to 3.17.
|
||||
|
|
|
@ -227,8 +227,9 @@ FLAGS_TO_PASS:=\
|
|||
CRT0S = crt1.o dllcrt1.o crt2.o dllcrt2.o CRT_noglob.o crtmt.o crtst.o \
|
||||
CRT_fp8.o CRT_fp10.o txtmode.o binmode.o
|
||||
MINGW_OBJS = CRTglob.o CRTfmode.o CRTinit.o dllmain.o gccmain.o \
|
||||
main.o crtst.o mthr_stub.o CRT_fp10.o txtmode.o \
|
||||
pseudo-reloc.o pseudo-reloc-list.o cpu_features.o
|
||||
main.o crtst.o CRT_fp10.o txtmode.o \
|
||||
pseudo-reloc.o pseudo-reloc-list.o cpu_features.o \
|
||||
tlsmcrt.o tlsmthread.o tlssup.o tlsthrd.o
|
||||
|
||||
MOLD_OBJS = isascii.o iscsym.o iscsymf.o toascii.o \
|
||||
strcasecmp.o strncasecmp.o wcscmpi.o
|
||||
|
@ -247,6 +248,7 @@ LIBS = libcrtdll.a \
|
|||
libmoldname80.a libmoldname80d.a \
|
||||
libmoldname90.a libmoldname90d.a \
|
||||
$(LIBM_A) \
|
||||
libmingwthrd_old.a \
|
||||
libmingwthrd.a
|
||||
|
||||
DLLS = $(THREAD_DLL_NAME)
|
||||
|
@ -260,7 +262,7 @@ Makefile.in README TODO config.guess config.sub configure configure.in \
|
|||
aclocal.m4 crt1.c crtdll.def crtmt.c crtst.c dllcrt1.c dllmain.c \
|
||||
gccmain.c init.c install-sh jamfile main.c mkinstalldirs \
|
||||
moldname.def.in msvcrt.def.in ofmt_stub.s \
|
||||
mthr.c mthr_init.c mthr_stub.c readme.txt \
|
||||
mthr.c mthr_init.c tlsmcrt.c tlsmthread.c tlssup.c tlsthrd.c readme.txt \
|
||||
isascii.c iscsym.c iscsymf.c toascii.c \
|
||||
strcasecmp.c strncasecmp.c wcscmpi.c \
|
||||
CRT_fp8.c CRT_fp10.c test_headers.c txtmode.c binmode.c pseudo-reloc.c \
|
||||
|
@ -290,7 +292,11 @@ libm.a: _libm_dummy.o
|
|||
$(AR) rc $@ _libm_dummy.o
|
||||
$(RANLIB) $@
|
||||
|
||||
libmingwthrd.a: crtmt.o mingwthrd.def
|
||||
libmingwthrd.a: crtmt.o
|
||||
$(AR) $(ARFLAGS) $@ crtmt.o
|
||||
$(RANLIB) $@
|
||||
|
||||
libmingwthrd_old.a: crtmt.o mingwthrd.def
|
||||
$(DLLTOOL) $(DLLTOOL_FLAGS) --dllname $(THREAD_DLL_NAME) \
|
||||
--def mingwthrd.def --output-lib $@
|
||||
$(AR) $(ARFLAGS) $@ crtmt.o
|
||||
|
|
|
@ -34,6 +34,9 @@ extern void _pei386_runtime_relocator (void);
|
|||
|
||||
extern int main (int, char **, char **);
|
||||
|
||||
/* TLS initialization hook. */
|
||||
extern const PIMAGE_TLS_CALLBACK __dyn_tls_init_callback;
|
||||
|
||||
/*
|
||||
* Must have the correct app type for MSVCRT.
|
||||
*/
|
||||
|
@ -186,6 +189,10 @@ __mingw_CRTStartup (void)
|
|||
{
|
||||
int nRet;
|
||||
|
||||
/* Initialize TLS callback. */
|
||||
if (__dyn_tls_init_callback != NULL)
|
||||
__dyn_tls_init_callback (NULL, DLL_THREAD_ATTACH, NULL);
|
||||
|
||||
/*
|
||||
* Set up the top-level exception handler so that signal handling
|
||||
* works as expected. The mapping between ANSI/POSIX signals and
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
#include <errno.h>
|
||||
#include <windows.h>
|
||||
|
||||
/* TLS initialization hook. */
|
||||
extern const PIMAGE_TLS_CALLBACK __dyn_tls_init_callback;
|
||||
|
||||
/* Unlike normal crt1, I don't initialize the FPU, because the process
|
||||
* should have done that already. I also don't set the file handle modes,
|
||||
* because that would be rude. */
|
||||
|
@ -62,6 +65,12 @@ DllMainCRTStartup (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
|
|||
*first_atexit = NULL;
|
||||
next_atexit = first_atexit;
|
||||
|
||||
/* Initialize TLS callback. */
|
||||
if (__dyn_tls_init_callback != NULL)
|
||||
{
|
||||
__dyn_tls_init_callback (hDll, DLL_THREAD_ATTACH, lpReserved);
|
||||
}
|
||||
|
||||
/* Adust references to dllimported data (from other DLL's)
|
||||
that have non-zero offsets. */
|
||||
_pei386_runtime_relocator ();
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
* mthr_stub.c
|
||||
*
|
||||
* Implement Mingw thread-support stubs for single-threaded C++ apps.
|
||||
*
|
||||
* This file is used by if gcc is built with --enable-threads=win32 and
|
||||
* iff gcc does *NOT* use -mthreads option.
|
||||
*
|
||||
* The -mthreads implementation is in mthr.c.
|
||||
*
|
||||
* Created by Mumit Khan <khan@nanotech.wisc.edu>
|
||||
*
|
||||
*/
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
|
||||
/*
|
||||
* __mingwthr_register_key_dtor (DWORD key, void (*dtor) (void *))
|
||||
*
|
||||
* Public interface called by C++ exception handling mechanism in
|
||||
* libgcc (cf: __gthread_key_create).
|
||||
* No-op versions.
|
||||
*/
|
||||
|
||||
int
|
||||
__mingwthr_key_dtor (DWORD key, void (*dtor) (void *))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf ("%s: ignoring key: (%ld) / dtor: (%x)\n",
|
||||
__FUNCTION__, key, dtor);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
__mingwthr_remove_key_dtor (DWORD key )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf ("%s: ignoring key: (%ld)\n", __FUNCTION__, key );
|
||||
#endif
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* This file has no copyright assigned and is placed in the Public Domain.
|
||||
* This file is part of the w64 mingw-runtime package.
|
||||
* No warranty is given; refer to the file DISCLAIMER within this package.
|
||||
*
|
||||
* Written by Kai Tietz <kai.tietz@onevision.com>
|
||||
*/
|
||||
|
||||
/* We support TLS cleanup code in any case. If shared version of libgcc is used _CRT_MT has value 1,
|
||||
otherwise
|
||||
we do tls cleanup in runtime and _CRT_MT has value 2. */
|
||||
int _CRT_MT = 2;
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
* This file has no copyright assigned and is placed in the Public Domain.
|
||||
* This file is part of the w64 mingw-runtime package.
|
||||
* No warranty is given; refer to the file DISCLAIMER within this package.
|
||||
*
|
||||
* Written by Kai Tietz <kai.tietz@onevision.com>
|
||||
*/
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int __mingwthr_key_dtor (DWORD key, void (*dtor)(void *));
|
||||
int __mingwthr_remove_key_dtor (DWORD key);
|
||||
|
||||
extern int ___w64_mingwthr_remove_key_dtor (DWORD key);
|
||||
extern int ___w64_mingwthr_add_key_dtor (DWORD key, void (*dtor)(void *));
|
||||
|
||||
|
||||
#ifndef _WIN64
|
||||
#define MINGWM10_DLL "mingwm10.dll"
|
||||
typedef int (*fMTRemoveKeyDtor)(DWORD key);
|
||||
typedef int (*fMTKeyDtor)(DWORD key, void (*dtor)(void *));
|
||||
extern fMTRemoveKeyDtor __mingw_gMTRemoveKeyDtor;
|
||||
extern fMTKeyDtor __mingw_gMTKeyDtor;
|
||||
extern int __mingw_usemthread_dll;
|
||||
#endif
|
||||
|
||||
int
|
||||
__mingwthr_remove_key_dtor (DWORD key)
|
||||
{
|
||||
#ifndef _WIN64
|
||||
if (!__mingw_usemthread_dll)
|
||||
#endif
|
||||
return ___w64_mingwthr_remove_key_dtor (key);
|
||||
#ifndef _WIN64
|
||||
if (__mingw_gMTRemoveKeyDtor)
|
||||
return (*__mingw_gMTRemoveKeyDtor) (key);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
__mingwthr_key_dtor (DWORD key, void (*dtor)(void *))
|
||||
{
|
||||
if (dtor)
|
||||
{
|
||||
#ifndef _WIN64
|
||||
if (!__mingw_usemthread_dll)
|
||||
#endif
|
||||
return ___w64_mingwthr_add_key_dtor (key, dtor);
|
||||
#ifndef _WIN64
|
||||
if (__mingw_gMTKeyDtor)
|
||||
return (*__mingw_gMTKeyDtor) (key, dtor);
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,213 @@
|
|||
/**
|
||||
* This file has no copyright assigned and is placed in the Public Domain.
|
||||
* This file is part of the w64 mingw-runtime package.
|
||||
* No warranty is given; refer to the file DISCLAIMER within this package.
|
||||
*
|
||||
* Written by Kai Tietz <kai.tietz@onevision.com>
|
||||
*/
|
||||
|
||||
#ifdef CRTDLL
|
||||
#undef CRTDLL
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#ifndef _CRTALLOC
|
||||
#define _CRTALLOC(x) __attribute__ ((section (x) ))
|
||||
#endif
|
||||
|
||||
#ifndef __INTERNAL_FUNC_DEFINED
|
||||
#define __INTERNAL_FUNC_DEFINED
|
||||
typedef void (__cdecl *_PVFV)(void);
|
||||
typedef int (__cdecl *_PIFV)(void);
|
||||
typedef void (__cdecl *_PVFI)(int);
|
||||
#endif
|
||||
|
||||
extern WINBOOL __mingw_TLScallback (HANDLE hDllHandle, DWORD reason, LPVOID reserved);
|
||||
|
||||
#define FUNCS_PER_NODE 30
|
||||
|
||||
typedef struct TlsDtorNode {
|
||||
int count;
|
||||
struct TlsDtorNode *next;
|
||||
_PVFV funcs[FUNCS_PER_NODE];
|
||||
} TlsDtorNode;
|
||||
|
||||
ULONG _tls_index = 0;
|
||||
|
||||
/* TLS raw template data start and end. */
|
||||
_CRTALLOC(".tls$AAA") char _tls_start = 0;
|
||||
_CRTALLOC(".tls$ZZZ") char _tls_end = 0;
|
||||
|
||||
_CRTALLOC(".CRT$XLA") PIMAGE_TLS_CALLBACK __xl_a = 0;
|
||||
_CRTALLOC(".CRT$XLZ") PIMAGE_TLS_CALLBACK __xl_z = 0;
|
||||
|
||||
#ifdef _WIN64
|
||||
_CRTALLOC(".tls") const IMAGE_TLS_DIRECTORY64 _tls_used = {
|
||||
(ULONGLONG) &_tls_start+1, (ULONGLONG) &_tls_end, (ULONGLONG) &_tls_index,
|
||||
(ULONGLONG) (&__xl_a+1), (ULONG) 0, (ULONG) 0
|
||||
};
|
||||
#else
|
||||
_CRTALLOC(".tls") const IMAGE_TLS_DIRECTORY _tls_used = {
|
||||
(ULONG)(ULONG_PTR) &_tls_start+1, (ULONG)(ULONG_PTR) &_tls_end,
|
||||
(ULONG)(ULONG_PTR) &_tls_index, (ULONG)(ULONG_PTR) (&__xl_a+1),
|
||||
(ULONG) 0, (ULONG) 0
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef __CRT_THREAD
|
||||
#ifdef HAVE_ATTRIBUTE_THREAD
|
||||
#define __CRT_THREAD __declspec(thread)
|
||||
#else
|
||||
#define __CRT_THREAD __thread
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define DISABLE_MS_TLS 1
|
||||
|
||||
static _CRTALLOC(".CRT$XDA") _PVFV __xd_a = 0;
|
||||
static _CRTALLOC(".CRT$XDZ") _PVFV __xd_z = 0;
|
||||
|
||||
#if !defined (DISABLE_MS_TLS)
|
||||
static __CRT_THREAD TlsDtorNode *dtor_list;
|
||||
static __CRT_THREAD TlsDtorNode dtor_list_head;
|
||||
#endif
|
||||
|
||||
extern int _CRT_MT;
|
||||
|
||||
#ifndef _WIN64
|
||||
#define MINGWM10_DLL "mingwm10.dll"
|
||||
typedef int (*fMTRemoveKeyDtor)(DWORD key);
|
||||
typedef int (*fMTKeyDtor)(DWORD key, void (*dtor)(void *));
|
||||
fMTRemoveKeyDtor __mingw_gMTRemoveKeyDtor;
|
||||
fMTKeyDtor __mingw_gMTKeyDtor;
|
||||
int __mingw_usemthread_dll;
|
||||
static HANDLE __mingw_mthread_hdll;
|
||||
#endif
|
||||
|
||||
BOOL WINAPI __dyn_tls_init (HANDLE, DWORD, LPVOID);
|
||||
|
||||
BOOL WINAPI
|
||||
__dyn_tls_init (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
|
||||
{
|
||||
_PVFV *pfunc;
|
||||
|
||||
#ifndef _WIN64
|
||||
if (_winmajor < 4)
|
||||
{
|
||||
__mingw_usemthread_dll = 1;
|
||||
__mingw_mthread_hdll = LoadLibrary (MINGWM10_DLL);
|
||||
if (__mingw_mthread_hdll != NULL)
|
||||
{
|
||||
__mingw_gMTRemoveKeyDtor = (fMTRemoveKeyDtor) GetProcAddress (__mingw_mthread_hdll, "__mingwthr_remove_key_dtor");
|
||||
__mingw_gMTKeyDtor = (fMTKeyDtor) GetProcAddress (__mingw_mthread_hdll, "__mingwthr_key_dtor");
|
||||
}
|
||||
if (__mingw_mthread_hdll == NULL || !__mingw_gMTRemoveKeyDtor || !__mingw_gMTKeyDtor)
|
||||
{
|
||||
__mingw_gMTKeyDtor = NULL;
|
||||
__mingw_gMTRemoveKeyDtor = NULL;
|
||||
if (__mingw_mthread_hdll)
|
||||
FreeLibrary (__mingw_mthread_hdll);
|
||||
__mingw_mthread_hdll = NULL;
|
||||
_CRT_MT = 0;
|
||||
return TRUE;
|
||||
}
|
||||
_CRT_MT = 1;
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
/* We don't let us trick here. */
|
||||
if (_CRT_MT != 2)
|
||||
_CRT_MT = 2;
|
||||
|
||||
if (dwReason != DLL_THREAD_ATTACH)
|
||||
{
|
||||
if (dwReason == DLL_PROCESS_ATTACH)
|
||||
__mingw_TLScallback (hDllHandle, dwReason, lpreserved);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
for (pfunc = &__xd_a + 1; pfunc != &__xd_z; ++pfunc)
|
||||
{
|
||||
if (*pfunc != NULL)
|
||||
(*pfunc)();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
const PIMAGE_TLS_CALLBACK __dyn_tls_init_callback = (const PIMAGE_TLS_CALLBACK) __dyn_tls_init;
|
||||
_CRTALLOC(".CRT$XLC") PIMAGE_TLS_CALLBACK __xl_c = (PIMAGE_TLS_CALLBACK) __dyn_tls_init;
|
||||
|
||||
int __cdecl __tlregdtor (_PVFV);
|
||||
|
||||
int __cdecl
|
||||
__tlregdtor (_PVFV func)
|
||||
{
|
||||
if (!func)
|
||||
return 0;
|
||||
#if !defined (DISABLE_MS_TLS)
|
||||
if (dtor_list == NULL)
|
||||
{
|
||||
dtor_list = &dtor_list_head;
|
||||
dtor_list_head.count = 0;
|
||||
}
|
||||
else if (dtor_list->count == FUNCS_PER_NODE)
|
||||
{
|
||||
TlsDtorNode *pnode = (TlsDtorNode *) malloc (sizeof (TlsDtorNode));
|
||||
if (pnode == NULL)
|
||||
return -1;
|
||||
pnode->count = 0;
|
||||
pnode->next = dtor_list;
|
||||
dtor_list = pnode;
|
||||
|
||||
dtor_list->count = 0;
|
||||
}
|
||||
dtor_list->funcs[dtor_list->count++] = func;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static BOOL WINAPI
|
||||
__dyn_tls_dtor (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
|
||||
{
|
||||
#if !defined (DISABLE_MS_TLS)
|
||||
TlsDtorNode *pnode, *pnext;
|
||||
int i;
|
||||
#endif
|
||||
|
||||
if (dwReason != DLL_THREAD_DETACH && dwReason != DLL_PROCESS_DETACH)
|
||||
return TRUE;
|
||||
/* As TLS variables are detroyed already by DLL_THREAD_DETACH
|
||||
call, we have to avoid access on the possible DLL_PROCESS_DETACH
|
||||
call the already destroyed TLS vars.
|
||||
TODO: The used local thread based variables have to be handled
|
||||
manually, so that we can control their lifetime here. */
|
||||
#if !defined (DISABLE_MS_TLS)
|
||||
if (dwReason != DLL_PROCESS_DETACH)
|
||||
{
|
||||
for (pnode = dtor_list; pnode != NULL; pnode = pnext)
|
||||
{
|
||||
for (i = pnode->count - 1; i >= 0; --i)
|
||||
{
|
||||
if (pnode->funcs[i] != NULL)
|
||||
(*pnode->funcs[i])();
|
||||
}
|
||||
pnext = pnode->next;
|
||||
if (pnext != NULL)
|
||||
free ((void *) pnode);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
__mingw_TLScallback (hDllHandle, dwReason, lpreserved);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
_CRTALLOC(".CRT$XLD") PIMAGE_TLS_CALLBACK __xl_d = (PIMAGE_TLS_CALLBACK) __dyn_tls_dtor;
|
||||
|
||||
|
||||
int mingw_initltsdrot_force = 0;
|
||||
int mingw_initltsdyn_force=0;
|
||||
int mingw_initltssuo_force = 0;
|
|
@ -0,0 +1,148 @@
|
|||
/**
|
||||
* This file has no copyright assigned and is placed in the Public Domain.
|
||||
* This file is part of the w64 mingw-runtime package.
|
||||
* No warranty is given; refer to the file DISCLAIMER within this package.
|
||||
*
|
||||
* Written by Kai Tietz <kai.tietz@onevision.com>
|
||||
*
|
||||
* This file is used by if gcc is built with --enable-threads=win32.
|
||||
*
|
||||
* Based on version created by Mumit Khan <khan@nanotech.wisc.edu>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
WINBOOL __mingw_TLScallback (HANDLE hDllHandle, DWORD reason, LPVOID reserved);
|
||||
int ___w64_mingwthr_remove_key_dtor (DWORD key);
|
||||
int ___w64_mingwthr_add_key_dtor (DWORD key, void (*dtor)(void *));
|
||||
|
||||
/* To protect the thread/key association data structure modifications. */
|
||||
static CRITICAL_SECTION __mingwthr_cs;
|
||||
static volatile int __mingwthr_cs_init = 0;
|
||||
|
||||
typedef struct __mingwthr_key __mingwthr_key_t;
|
||||
|
||||
/* The list of threads active with key/dtor pairs. */
|
||||
struct __mingwthr_key {
|
||||
DWORD key;
|
||||
void (*dtor)(void *);
|
||||
__mingwthr_key_t volatile *next;
|
||||
};
|
||||
|
||||
|
||||
static __mingwthr_key_t volatile *key_dtor_list;
|
||||
|
||||
int
|
||||
___w64_mingwthr_add_key_dtor (DWORD key, void (*dtor)(void *))
|
||||
{
|
||||
__mingwthr_key_t *new_key;
|
||||
|
||||
if (__mingwthr_cs_init == 0)
|
||||
return 0;
|
||||
new_key = (__mingwthr_key_t *) calloc (1, sizeof (__mingwthr_key_t));
|
||||
if (new_key == NULL)
|
||||
return -1;
|
||||
|
||||
new_key->key = key;
|
||||
new_key->dtor = dtor;
|
||||
|
||||
EnterCriticalSection (&__mingwthr_cs);
|
||||
|
||||
new_key->next = key_dtor_list;
|
||||
key_dtor_list = new_key;
|
||||
|
||||
LeaveCriticalSection (&__mingwthr_cs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
___w64_mingwthr_remove_key_dtor (DWORD key)
|
||||
{
|
||||
__mingwthr_key_t volatile *prev_key;
|
||||
__mingwthr_key_t volatile *cur_key;
|
||||
|
||||
if (__mingwthr_cs_init == 0)
|
||||
return 0;
|
||||
|
||||
EnterCriticalSection (&__mingwthr_cs);
|
||||
|
||||
prev_key = NULL;
|
||||
cur_key = key_dtor_list;
|
||||
|
||||
while (cur_key != NULL)
|
||||
{
|
||||
if ( cur_key->key == key)
|
||||
{
|
||||
if (prev_key == NULL)
|
||||
key_dtor_list = cur_key->next;
|
||||
else
|
||||
prev_key->next = cur_key->next;
|
||||
|
||||
free ((void*)cur_key);
|
||||
break;
|
||||
}
|
||||
prev_key = cur_key;
|
||||
cur_key = cur_key->next;
|
||||
}
|
||||
|
||||
LeaveCriticalSection (&__mingwthr_cs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
__mingwthr_run_key_dtors (void)
|
||||
{
|
||||
__mingwthr_key_t volatile *keyp;
|
||||
|
||||
if (__mingwthr_cs_init == 0)
|
||||
return;
|
||||
EnterCriticalSection (&__mingwthr_cs);
|
||||
|
||||
for (keyp = key_dtor_list; keyp; )
|
||||
{
|
||||
LPVOID value = TlsGetValue (keyp->key);
|
||||
if (GetLastError () == ERROR_SUCCESS)
|
||||
{
|
||||
if (value)
|
||||
(*keyp->dtor) (value);
|
||||
}
|
||||
keyp = keyp->next;
|
||||
}
|
||||
|
||||
LeaveCriticalSection (&__mingwthr_cs);
|
||||
}
|
||||
|
||||
WINBOOL
|
||||
__mingw_TLScallback (HANDLE hDllHandle __attribute__ ((__unused__)),
|
||||
DWORD reason,
|
||||
LPVOID reserved __attribute__ ((__unused__)))
|
||||
{
|
||||
switch (reason)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
if (__mingwthr_cs_init == 0)
|
||||
InitializeCriticalSection (&__mingwthr_cs);
|
||||
__mingwthr_cs_init = 1;
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
__mingwthr_run_key_dtors();
|
||||
if (__mingwthr_cs_init == 1)
|
||||
{
|
||||
__mingwthr_cs_init = 0;
|
||||
DeleteCriticalSection (&__mingwthr_cs);
|
||||
}
|
||||
break;
|
||||
case DLL_THREAD_ATTACH:
|
||||
break;
|
||||
case DLL_THREAD_DETACH:
|
||||
__mingwthr_run_key_dtors();
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
Loading…
Reference in New Issue