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:
148
winsup/mingw/tlsthrd.c
Normal file
148
winsup/mingw/tlsthrd.c
Normal file
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user