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>
|
2009-11-29 Chris Sutcliffe <ir0nh34d@users.sourceforge.net>
|
||||||
|
|
||||||
* include/_mingw.h: Increment version to 3.17.
|
* 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 \
|
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
|
CRT_fp8.o CRT_fp10.o txtmode.o binmode.o
|
||||||
MINGW_OBJS = CRTglob.o CRTfmode.o CRTinit.o dllmain.o gccmain.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 \
|
main.o crtst.o CRT_fp10.o txtmode.o \
|
||||||
pseudo-reloc.o pseudo-reloc-list.o cpu_features.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 \
|
MOLD_OBJS = isascii.o iscsym.o iscsymf.o toascii.o \
|
||||||
strcasecmp.o strncasecmp.o wcscmpi.o
|
strcasecmp.o strncasecmp.o wcscmpi.o
|
||||||
|
@ -247,6 +248,7 @@ LIBS = libcrtdll.a \
|
||||||
libmoldname80.a libmoldname80d.a \
|
libmoldname80.a libmoldname80d.a \
|
||||||
libmoldname90.a libmoldname90d.a \
|
libmoldname90.a libmoldname90d.a \
|
||||||
$(LIBM_A) \
|
$(LIBM_A) \
|
||||||
|
libmingwthrd_old.a \
|
||||||
libmingwthrd.a
|
libmingwthrd.a
|
||||||
|
|
||||||
DLLS = $(THREAD_DLL_NAME)
|
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 \
|
aclocal.m4 crt1.c crtdll.def crtmt.c crtst.c dllcrt1.c dllmain.c \
|
||||||
gccmain.c init.c install-sh jamfile main.c mkinstalldirs \
|
gccmain.c init.c install-sh jamfile main.c mkinstalldirs \
|
||||||
moldname.def.in msvcrt.def.in ofmt_stub.s \
|
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 \
|
isascii.c iscsym.c iscsymf.c toascii.c \
|
||||||
strcasecmp.c strncasecmp.c wcscmpi.c \
|
strcasecmp.c strncasecmp.c wcscmpi.c \
|
||||||
CRT_fp8.c CRT_fp10.c test_headers.c txtmode.c binmode.c pseudo-reloc.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
|
$(AR) rc $@ _libm_dummy.o
|
||||||
$(RANLIB) $@
|
$(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) \
|
$(DLLTOOL) $(DLLTOOL_FLAGS) --dllname $(THREAD_DLL_NAME) \
|
||||||
--def mingwthrd.def --output-lib $@
|
--def mingwthrd.def --output-lib $@
|
||||||
$(AR) $(ARFLAGS) $@ crtmt.o
|
$(AR) $(ARFLAGS) $@ crtmt.o
|
||||||
|
|
|
@ -34,6 +34,9 @@ extern void _pei386_runtime_relocator (void);
|
||||||
|
|
||||||
extern int main (int, char **, char **);
|
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.
|
* Must have the correct app type for MSVCRT.
|
||||||
*/
|
*/
|
||||||
|
@ -186,6 +189,10 @@ __mingw_CRTStartup (void)
|
||||||
{
|
{
|
||||||
int nRet;
|
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
|
* Set up the top-level exception handler so that signal handling
|
||||||
* works as expected. The mapping between ANSI/POSIX signals and
|
* works as expected. The mapping between ANSI/POSIX signals and
|
||||||
|
|
|
@ -14,6 +14,9 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <windows.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
|
/* 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,
|
* should have done that already. I also don't set the file handle modes,
|
||||||
* because that would be rude. */
|
* because that would be rude. */
|
||||||
|
@ -62,6 +65,12 @@ DllMainCRTStartup (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
|
||||||
*first_atexit = NULL;
|
*first_atexit = NULL;
|
||||||
next_atexit = first_atexit;
|
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)
|
/* Adust references to dllimported data (from other DLL's)
|
||||||
that have non-zero offsets. */
|
that have non-zero offsets. */
|
||||||
_pei386_runtime_relocator ();
|
_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