* cygtls.h: Add more "don't parse this" guards.

(_threadinfo::init_thread): Rename from 'init'.
(_threadinfo::init): Declare new function.
(_threadinfo::protect_linked_list): Declare new critical section.
* dcrt0.cc (dll_crt0_1): Call init_thread to initialize thread stuff.
(_dll_crt0): Call _threadinfo::init prior to invoking dll_crt0_1.
* exceptions.cc (_threadinfo::init_thread): Rename from 'init'.
(_threadinfo::init): Define new function.  Protect linked list manipulation
with new critical section.
(_threadinfo::call): Reflect function name change.
(_threadinfo::remove): Protect linked list manipulation with new critical
section
* gentls_offsets: Rework to allow multi-line "don't parse this" protection.
* init.cc (dll_entry): Don't remove threads info stuff here since the remove
function uses a critical section which can't be used during thread creation or
destruction.
* thread.cc (pthread::exit): Call _threadinfo remove function here.
This commit is contained in:
Christopher Faylor 2003-12-06 18:08:38 +00:00
parent bdfb870e4a
commit 2b6d15a908
7 changed files with 56 additions and 12 deletions

View File

@ -1,3 +1,24 @@
2003-12-06 Christopher Faylor <cgf@redhat.com>
* cygtls.h: Add more "don't parse this" guards.
(_threadinfo::init_thread): Rename from 'init'.
(_threadinfo::init): Declare new function.
(_threadinfo::protect_linked_list): Declare new critical section.
* dcrt0.cc (dll_crt0_1): Call init_thread to initialize thread stuff.
(_dll_crt0): Call _threadinfo::init prior to invoking dll_crt0_1.
* exceptions.cc (_threadinfo::init_thread): Rename from 'init'.
(_threadinfo::init): Define new function. Protect linked list
manipulation with new critical section.
(_threadinfo::call): Reflect function name change.
(_threadinfo::remove): Protect linked list manipulation with new
critical section
* gentls_offsets: Rework to allow multi-line "don't parse this"
protection.
* init.cc (dll_entry): Don't remove threads info stuff here since the
remove function uses a critical section which can't be used during
thread creation or destruction.
* thread.cc (pthread::exit): Call _threadinfo remove function here.
2003-12-05 Christopher Faylor <cgf@redhat.com> 2003-12-05 Christopher Faylor <cgf@redhat.com>
* cygthread.cc (cygthread::stub2): Remove myself from the list of * cygthread.cc (cygthread::stub2): Remove myself from the list of

View File

@ -16,7 +16,7 @@ details. */
/* Please keep this file simple. Changes to the below structure may require /* Please keep this file simple. Changes to the below structure may require
acompanying changes to the very simple parser in the perl script acompanying changes to the very simple parser in the perl script
'gentls_offsets'. */ 'gentls_offsets' (<<-- start parsing here). */
#pragma pack(push,4) #pragma pack(push,4)
typedef __uint32_t __stack_t; typedef __uint32_t __stack_t;
@ -40,7 +40,10 @@ struct _threadinfo
int sig; int sig;
__stack_t *stackptr; __stack_t *stackptr;
void init (void *); /*gentls_offsets*/
static CRITICAL_SECTION protect_linked_list;
static void init ();
void init_thread (void *);
static void call (void (*) (void *, void *), void *); static void call (void (*) (void *, void *), void *);
void call2 (void (*) (void *, void *), void *, void *); void call2 (void (*) (void *, void *), void *, void *);
void remove (); void remove ();
@ -54,6 +57,7 @@ struct _threadinfo
void __stdcall interrupt_setup (int sig, void *handler, struct sigaction& siga, __stack_t retaddr) void __stdcall interrupt_setup (int sig, void *handler, struct sigaction& siga, __stack_t retaddr)
__attribute__((regparm(3))); __attribute__((regparm(3)));
operator HANDLE () const {return tid->win32_obj_id;} operator HANDLE () const {return tid->win32_obj_id;}
/*gentls_offsets*/
}; };
#pragma pack(pop) #pragma pack(pop)

View File

@ -534,7 +534,7 @@ dll_crt0_1 ()
{ {
char padding[CYGTLS_PADSIZE]; char padding[CYGTLS_PADSIZE];
_main_tls = &_my_tls; _main_tls = &_my_tls;
_main_tls->init (padding); _main_tls->init_thread (padding);
/* According to onno@stack.urc.tue.nl, the exception handler record must /* According to onno@stack.urc.tue.nl, the exception handler record must
be on the stack. */ be on the stack. */
@ -901,6 +901,8 @@ _dll_crt0 ()
break; break;
} }
} }
_threadinfo::init ();
dll_crt0_1 (); dll_crt0_1 ();
} }

View File

@ -40,6 +40,8 @@ _threadinfo NO_COPY dummy_thread;
_threadinfo NO_COPY *_last_thread = &dummy_thread; _threadinfo NO_COPY *_last_thread = &dummy_thread;
extern _threadinfo *_main_tls; extern _threadinfo *_main_tls;
CRITICAL_SECTION NO_COPY _threadinfo::protect_linked_list;
extern DWORD sigtid; extern DWORD sigtid;
extern HANDLE hExeced; extern HANDLE hExeced;
@ -157,18 +159,28 @@ _threadinfo::call (void (*func) (void *, void *), void *arg)
void void
_threadinfo::call2 (void (*func) (void *, void *), void *arg, void *buf) _threadinfo::call2 (void (*func) (void *, void *), void *arg, void *buf)
{ {
init (buf); init_thread (buf);
func (arg, buf); func (arg, buf);
} }
void void
_threadinfo::init (void *) _threadinfo::init ()
{
InitializeCriticalSection (&protect_linked_list);
}
void
_threadinfo::init_thread (void *)
{ {
memset (this, 0, sizeof (*this)); memset (this, 0, sizeof (*this));
stackptr = stack; stackptr = stack;
EnterCriticalSection (&protect_linked_list);
prev = _last_thread; prev = _last_thread;
_last_thread->next = this; _last_thread->next = this;
_last_thread = this; _last_thread = this;
LeaveCriticalSection (&protect_linked_list);
set_state (false); set_state (false);
errno_addr = &errno; errno_addr = &errno;
} }
@ -177,6 +189,7 @@ void
_threadinfo::remove () _threadinfo::remove ()
{ {
_threadinfo *t; _threadinfo *t;
EnterCriticalSection (&protect_linked_list);
for (t = _last_thread; t && t != this; t = t->prev) for (t = _last_thread; t && t != this; t = t->prev)
continue; continue;
if (!t) if (!t)
@ -186,6 +199,7 @@ _threadinfo::remove ()
t->next->prev = t->prev; t->next->prev = t->prev;
if (t == _last_thread) if (t == _last_thread)
_last_thread = t->prev; _last_thread = t->prev;
LeaveCriticalSection (&protect_linked_list);
} }
void void

View File

@ -5,8 +5,10 @@ open(TLS, $tls) or die "$0: couldn't open tls file \"$tls\" - $!\n";
my $struct = ''; my $struct = '';
my @fields = (); my @fields = ();
my $def = ''; my $def = '';
while (<TLS>) { my $tls = join('', <TLS>);
next if $struct && (!/gentls_offsets/o && /\(/o); $tls =~ s/\A.*?gentls_offsets[^\n]*\n//os;
$tls =~ s%/\*\s*gentls_offsets.*?/\*\s*gentls_offsets\s*\*/%%ogs;
foreach ($tls =~ /^.*\n/mg) {
$def .= $_ if $struct; $def .= $_ if $struct;
last if /^};/o; last if /^};/o;
/^\s*typedef/o and do { /^\s*typedef/o and do {
@ -20,7 +22,6 @@ while (<TLS>) {
} }
next; next;
} }
s%/\*\s*gentls_offsets.*/\*\s*gentls_offsets\s*\*/%%og;
s/(?:\[[^\]]*\]|struct|class)//o; s/(?:\[[^\]]*\]|struct|class)//o;
s/^\s+\S+\s+//o; s/^\s+\S+\s+//o;
s/[\*\s()]+//go; s/[\*\s()]+//go;
@ -31,6 +32,7 @@ while (<TLS>) {
close TLS; close TLS;
open(TMP, '>', "/tmp/$$.cc") or die "$0: couldn't open temporary index file \"/tmp/$$.c\" - $!\n"; open(TMP, '>', "/tmp/$$.cc") or die "$0: couldn't open temporary index file \"/tmp/$$.c\" - $!\n";
print TMP <<EOF; print TMP <<EOF;
#define __attribute__(X)
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <signal.h> #include <signal.h>

View File

@ -32,9 +32,6 @@ WINAPI dll_entry (HANDLE h, DWORD reason, void *static_load)
if (MT_INTERFACE->reent_key.set (&MT_INTERFACE->reents)) if (MT_INTERFACE->reent_key.set (&MT_INTERFACE->reents))
api_fatal ("thread initialization failed"); api_fatal ("thread initialization failed");
break; break;
case DLL_THREAD_DETACH:
_my_tls.remove ();
break;
} }
return 1; return 1;
} }

View File

@ -392,10 +392,14 @@ pthread::exit (void *value_ptr)
(_reclaim_reent) (_REENT); (_reclaim_reent) (_REENT);
if (InterlockedDecrement (&MT_INTERFACE->threadcount) == 0) if (InterlockedDecrement (&MT_INTERFACE->threadcount) == 0)
::exit (0); ::exit (0);
else else
ExitThread (0); {
_my_tls.remove ();
ExitThread (0);
}
} }
int int