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