* 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:
parent
bdfb870e4a
commit
2b6d15a908
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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 ();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue