* 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>
|
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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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 ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -392,11 +392,15 @@ 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
|
||||||
|
{
|
||||||
|
_my_tls.remove ();
|
||||||
ExitThread (0);
|
ExitThread (0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pthread::cancel (void)
|
pthread::cancel (void)
|
||||||
|
|
Loading…
Reference in New Issue