* 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>
* 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
acompanying changes to the very simple parser in the perl script
'gentls_offsets'. */
'gentls_offsets' (<<-- start parsing here). */
#pragma pack(push,4)
typedef __uint32_t __stack_t;
@ -40,7 +40,10 @@ struct _threadinfo
int sig;
__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 *);
void call2 (void (*) (void *, void *), void *, void *);
void remove ();
@ -54,6 +57,7 @@ struct _threadinfo
void __stdcall interrupt_setup (int sig, void *handler, struct sigaction& siga, __stack_t retaddr)
__attribute__((regparm(3)));
operator HANDLE () const {return tid->win32_obj_id;}
/*gentls_offsets*/
};
#pragma pack(pop)

View File

@ -534,7 +534,7 @@ dll_crt0_1 ()
{
char padding[CYGTLS_PADSIZE];
_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
be on the stack. */
@ -901,6 +901,8 @@ _dll_crt0 ()
break;
}
}
_threadinfo::init ();
dll_crt0_1 ();
}

View File

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

View File

@ -5,8 +5,10 @@ open(TLS, $tls) or die "$0: couldn't open tls file \"$tls\" - $!\n";
my $struct = '';
my @fields = ();
my $def = '';
while (<TLS>) {
next if $struct && (!/gentls_offsets/o && /\(/o);
my $tls = join('', <TLS>);
$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;
last if /^};/o;
/^\s*typedef/o and do {
@ -20,7 +22,6 @@ while (<TLS>) {
}
next;
}
s%/\*\s*gentls_offsets.*/\*\s*gentls_offsets\s*\*/%%og;
s/(?:\[[^\]]*\]|struct|class)//o;
s/^\s+\S+\s+//o;
s/[\*\s()]+//go;
@ -31,6 +32,7 @@ while (<TLS>) {
close TLS;
open(TMP, '>', "/tmp/$$.cc") or die "$0: couldn't open temporary index file \"/tmp/$$.c\" - $!\n";
print TMP <<EOF;
#define __attribute__(X)
#include <stdio.h>
#include <stdlib.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))
api_fatal ("thread initialization failed");
break;
case DLL_THREAD_DETACH:
_my_tls.remove ();
break;
}
return 1;
}

View File

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