Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2003-12-06 21:08:38 +0300
committerChristopher Faylor <me@cgf.cx>2003-12-06 21:08:38 +0300
commit2b6d15a90833dd2e3aa2aa758813e721fe94a0ca (patch)
tree62d68c6e884f3f1f357148775903a18dc0a58350
parentbdfb870e4afae49b54f98f8486ee04b41b153b28 (diff)
* 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.
-rw-r--r--winsup/cygwin/ChangeLog21
-rw-r--r--winsup/cygwin/cygtls.h8
-rw-r--r--winsup/cygwin/dcrt0.cc4
-rw-r--r--winsup/cygwin/exceptions.cc18
-rwxr-xr-xwinsup/cygwin/gentls_offsets8
-rw-r--r--winsup/cygwin/init.cc3
-rw-r--r--winsup/cygwin/thread.cc6
7 files changed, 56 insertions, 12 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index c4f16eba9..69df166d4 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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
diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h
index ec6087af8..20913bebd 100644
--- a/winsup/cygwin/cygtls.h
+++ b/winsup/cygwin/cygtls.h
@@ -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)
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index a0af0231b..575a2bacb 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -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 ();
}
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index bc6f6e6ed..cb2db165f 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -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
diff --git a/winsup/cygwin/gentls_offsets b/winsup/cygwin/gentls_offsets
index fe5fab96e..26432b364 100755
--- a/winsup/cygwin/gentls_offsets
+++ b/winsup/cygwin/gentls_offsets
@@ -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>
diff --git a/winsup/cygwin/init.cc b/winsup/cygwin/init.cc
index 7a5e65cce..dc2b1a717 100644
--- a/winsup/cygwin/init.cc
+++ b/winsup/cygwin/init.cc
@@ -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;
}
diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc
index a34cd8497..c0bdb8b0d 100644
--- a/winsup/cygwin/thread.cc
+++ b/winsup/cygwin/thread.cc
@@ -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