aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2005-09-14 14:00:07 +0000
committerChristopher Faylor <me@cgf.cx>2005-09-14 14:00:07 +0000
commita611ae50d5c1106988df7ec8b053efc332e35ae3 (patch)
tree0057df8d08fd439ed9bcfb06bd07538c6f2f9d6e
parent67483cb2cdee37aa435fd108cea5310a873925a3 (diff)
downloadnewlib-a611ae50d5c1106988df7ec8b053efc332e35ae3.zip
newlib-a611ae50d5c1106988df7ec8b053efc332e35ae3.tar.gz
newlib-a611ae50d5c1106988df7ec8b053efc332e35ae3.tar.bz2
* exceptions.cc (sigtid): Remove declaration.
(handle_exceptions): Use _sig_tls rather than sigtid to determine if this is the signal thread. (set_signal_mask): Ditto for conditionalized CGF code. * pinfo.cc (pinfo::exit): Exit the thread if we forcefully terminated the main thread * sigproc.cc (sigtid): Delete. (_sig_tls): Define. (sig_clear): Use _sig_tls rather than sigtid to determine if this is the signal thread. (sig_dispatch_pending): Ditto. (wait_sig): Set _sig_tls here. * dcrt0.cc (do_exit): Move sigproc_terminate call later since signal handling was still needed for subsequent stuff. Call sigproc_terminate with new exit_state value. * pinfo.cc (pinfo::exit): Call sigproc_terminate with new exit_state value. * sigproc.cc (proc_terminate): Remove unnecessary (void) parameter. (sigproc_terminate): Ditto. Add new argument to accept exit state to be set. (wait_sig): Reorganize __SIGEXIT handling. Add more debugging output. * winsup.h (sigproc_terminate): Declare with new exit_state argument. (exit_states): Reorganize to reflect new exit ordering of sigproc_terminate.
-rw-r--r--winsup/cygwin/ChangeLog30
-rw-r--r--winsup/cygwin/cygtls.h1
-rw-r--r--winsup/cygwin/dcrt0.cc24
-rw-r--r--winsup/cygwin/exceptions.cc6
-rw-r--r--winsup/cygwin/pinfo.cc12
-rw-r--r--winsup/cygwin/sigproc.cc42
-rw-r--r--winsup/cygwin/sigproc.h2
-rw-r--r--winsup/cygwin/winsup.h4
8 files changed, 79 insertions, 42 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index d83936a..d8ea238 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,33 @@
+2005-09-14 Christopher Faylor <cgf@timesys.com>
+
+ * exceptions.cc (sigtid): Remove declaration.
+ (handle_exceptions): Use _sig_tls rather than sigtid to determine if
+ this is the signal thread.
+ (set_signal_mask): Ditto for conditionalized CGF code.
+ * pinfo.cc (pinfo::exit): Exit the thread if we forcefully terminated
+ the main thread
+ * sigproc.cc (sigtid): Delete.
+ (_sig_tls): Define.
+ (sig_clear): Use _sig_tls rather than sigtid to determine if this is
+ the signal thread.
+ (sig_dispatch_pending): Ditto.
+ (wait_sig): Set _sig_tls here.
+
+2005-09-13 Christopher Faylor <cgf@timesys.com>
+
+ * dcrt0.cc (do_exit): Move sigproc_terminate call later since signal
+ handling was still needed for subsequent stuff. Call sigproc_terminate
+ with new exit_state value.
+ * pinfo.cc (pinfo::exit): Call sigproc_terminate with new exit_state
+ value.
+ * sigproc.cc (proc_terminate): Remove unnecessary (void) parameter.
+ (sigproc_terminate): Ditto. Add new argument to accept exit state to
+ be set.
+ (wait_sig): Reorganize __SIGEXIT handling. Add more debugging output.
+ * winsup.h (sigproc_terminate): Declare with new exit_state argument.
+ (exit_states): Reorganize to reflect new exit ordering of
+ sigproc_terminate.
+
2005-09-13 Christopher Faylor <cgf@timesys.com>
* dcrt0.cc (do_exit): Rely on sigproc_terminate to set exit_state
diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h
index 6275318..65994eb 100644
--- a/winsup/cygwin/cygtls.h
+++ b/winsup/cygwin/cygtls.h
@@ -248,6 +248,7 @@ extern char *_tlsbase __asm__ ("%fs:4");
extern char *_tlstop __asm__ ("%fs:8");
#define _my_tls (((_cygtls *) _tlsbase)[-1])
extern _cygtls *_main_tls;
+extern _cygtls *_sig_tls;
/*gentls_offsets*/
class myfault
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index b720766..f293901 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -1056,17 +1056,7 @@ do_exit (int status)
close_all_files ();
}
- if (exit_state < ES_SIGPROCTERMINATE)
- sigproc_terminate (); // sets exit_state directly
-
myself->stopsig = 0;
- if (exit_state < ES_TITLE)
- {
- exit_state = ES_TITLE;
- /* restore console title */
- if (old_title && display_title)
- set_console_title (old_title);
- }
if (exit_state < ES_HUP_PGRP)
{
@@ -1101,6 +1091,17 @@ do_exit (int status)
}
+ if (exit_state < ES_SIGPROCTERMINATE)
+ sigproc_terminate (ES_SIGPROCTERMINATE); // sets exit_state directly
+
+ if (exit_state < ES_TITLE)
+ {
+ exit_state = ES_TITLE;
+ /* restore console title */
+ if (old_title && display_title)
+ set_console_title (old_title);
+ }
+
if (exit_state < ES_TTY_TERMINATE)
{
exit_state = ES_TTY_TERMINATE;
@@ -1165,9 +1166,6 @@ __api_fatal (const char *fmt, ...)
WriteFile (h, buf, len, &done, 0);
}
- /* We are going down without mercy. Make sure we reset
- our process_state. */
- sigproc_terminate ();
#ifdef DEBUGGING
try_to_debug ();
#endif
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index 939ec89..0f61409 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -36,8 +36,6 @@ static int handle_exceptions (EXCEPTION_RECORD *, void *, CONTEXT *, void *);
extern void sigdelayed ();
};
-extern DWORD sigtid;
-
extern DWORD dwExeced;
static BOOL WINAPI ctrl_c_handler (DWORD);
@@ -528,7 +526,7 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *)
if (!me.fault_guarded ()
&& (!cygwin_finished_initializing
- || GetCurrentThreadId () == sigtid
+ || &_my_tls == _sig_tls
|| (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_DFL
|| (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_IGN
|| (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_ERR))
@@ -1002,7 +1000,7 @@ extern "C" void __stdcall
set_signal_mask (sigset_t newmask, sigset_t& oldmask)
{
#ifdef CGF
- if (GetCurrentThreadId () == sigtid)
+ if (&_my_tls == _sig_tls)
small_printf ("********* waiting in signal thread\n");
#endif
mask_sync.acquire (INFINITE);
diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc
index 9ce988d..5d0b890 100644
--- a/winsup/cygwin/pinfo.cc
+++ b/winsup/cygwin/pinfo.cc
@@ -136,8 +136,7 @@ pinfo::zap_cwd ()
void
pinfo::exit (DWORD n)
{
- sigproc_terminate ();
- exit_state = ES_FINAL;
+ sigproc_terminate (ES_FINAL);
cygthread::terminate ();
if (n != EXITCODE_NOSET)
@@ -165,20 +164,25 @@ pinfo::exit (DWORD n)
_my_tls.stackptr = _my_tls.stack;
if (&_my_tls == _main_tls)
{
- sigproc_printf ("Calling ExitProcess hProcess %p, n %p, exitcode %p",
+ sigproc_printf ("Calling ExitThread hProcess %p, n %p, exitcode %p",
hProcess, n, exitcode);
ExitThread (exitcode);
}
else if (hMainThread)
{
+#if 0 /* This would be nice, but I don't think that Windows guarantees that
+ TerminateThread will not block. */
sigproc_printf ("Calling TerminateThread since %p != %p, %p, n %p, exitcode %p",
&_my_tls, _main_tls, hProcess, n, exitcode);
TerminateThread (hMainThread, exitcode);
+ if (&_my_tls != _sig_tls)
+ ExitThread (0);
+#endif
}
sigproc_printf ("Calling ExitProcess since hMainthread is 0, hProcess %p, n %p, exitcode %p",
hProcess, n, exitcode);
- release ();
+ // release (); Could race with signal thread. Sigh.
ExitProcess (exitcode);
}
# undef self
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index 5427d46..d8fc2d3 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -72,7 +72,7 @@ Static waitq waitq_head = {0, 0, 0, 0, 0, 0, 0};// Start of queue for wait'ing t
static muto NO_COPY sync_proc_subproc; // Control access to subproc stuff
-DWORD NO_COPY sigtid = 0; // ID of the signal thread
+_cygtls NO_COPY *_sig_tls;
/* Function declarations */
static int __stdcall checkstate (waitq *) __attribute__ ((regparm (1)));
@@ -382,10 +382,9 @@ _cygtls::remove_wq (DWORD wait)
* will not become procs.
*/
void __stdcall
-proc_terminate (void)
+proc_terminate ()
{
sigproc_printf ("nprocs %d", nprocs);
- /* Signal processing is assumed to be blocked in this routine. */
if (nprocs)
{
sync_proc_subproc.acquire (WPSP);
@@ -414,7 +413,7 @@ proc_terminate (void)
void __stdcall
sig_clear (int target_sig)
{
- if (GetCurrentThreadId () != sigtid)
+ if (&_my_tls != _sig_tls)
sig_send (myself, -target_sig);
else
{
@@ -445,11 +444,11 @@ sigpending (sigset_t *mask)
void __stdcall
sig_dispatch_pending (bool fast)
{
- if (exit_state || GetCurrentThreadId () == sigtid || !sigq.start.next)
+ if (exit_state || &_my_tls == _sig_tls || !sigq.start.next)
{
#ifdef DEBUGGING
- sigproc_printf ("exit_state %d, cur thread id %p, sigtid %p, sigq.start.next %p",
- exit_state, GetCurrentThreadId (), sigtid, sigq.start.next);
+ sigproc_printf ("exit_state %d, cur thread id %p, _sig_tls %p, sigq.start.next %p",
+ exit_state, GetCurrentThreadId (), _sig_tls, sigq.start.next);
#endif
return;
}
@@ -498,13 +497,14 @@ sigproc_init ()
/* Called on process termination to terminate signal and process threads.
*/
void __stdcall
-sigproc_terminate (void)
+sigproc_terminate (exit_states es)
{
- if (exit_state > ES_SIGPROCTERMINATE)
+ exit_states prior_exit_state = exit_state;
+ exit_state = es;
+ if (prior_exit_state > ES_SIGPROCTERMINATE)
sigproc_printf ("already performed");
else
{
- exit_state = ES_SIGPROCTERMINATE;
sigproc_printf ("entering");
sig_send (myself_nowait, __SIGEXIT);
proc_terminate (); // clean up process stuff
@@ -1007,12 +1007,12 @@ wait_sig (VOID *self)
myself->process_state |= PID_ACTIVE;
myself->process_state &= ~PID_INITIALIZING;
+ _sig_tls = &_my_tls;
sigproc_printf ("myself->dwProcessId %u", myself->dwProcessId);
SetEvent (wait_sig_inited);
- sigtid = GetCurrentThreadId ();
exception_list el;
- _my_tls.init_threadlist_exceptions (&el);
+ _sig_tls->init_threadlist_exceptions (&el);
debug_printf ("entering ReadFile loop, readsig %p, myself->sendsig %p",
readsig, myself->sendsig);
@@ -1022,8 +1022,6 @@ wait_sig (VOID *self)
sigpacket pack;
if (!ReadFile (readsig, &pack, sizeof (pack), &nb, NULL))
break;
- if (exit_state || pack.si.si_signo == __SIGEXIT)
- break;
if (nb != sizeof (pack))
{
@@ -1083,6 +1081,9 @@ wait_sig (VOID *self)
clearwait = true;
}
break;
+ case __SIGEXIT:
+ sigproc_printf ("saw __SIGEXIT");
+ break; /* handle below */
default:
if (pack.si.si_signo < 0)
sig_clear (-pack.si.si_signo);
@@ -1120,18 +1121,23 @@ wait_sig (VOID *self)
SetEvent (pack.wakeup);
sigproc_printf ("signalled %p", pack.wakeup);
}
+ if (pack.si.si_signo == __SIGEXIT)
+ break;
}
my_sendsig = NULL;
- sigproc_printf ("done");
- if (WaitForSingleObject (hMainThread, 5000) == WAIT_OBJECT_0)
+ DWORD res = WaitForSingleObject (hMainThread, 10000);
+
+ if (res != WAIT_OBJECT_0)
+ sigproc_printf ("wait for main thread returned %d", res);
+ else
{
DWORD exitcode = 1;
myself.release ();
+ sigproc_printf ("calling ExitProcess, exitcode %p", exitcode);
GetExitCodeThread (hMainThread, &exitcode);
- sigproc_printf ("Calling ExitProcess, exitcode %p",
- exitcode);
ExitProcess (exitcode);
}
+ sigproc_printf ("exiting thread");
ExitThread (0);
}
diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h
index c135f32..a8895df 100644
--- a/winsup/cygwin/sigproc.h
+++ b/winsup/cygwin/sigproc.h
@@ -73,7 +73,7 @@ int __stdcall proc_subproc (DWORD, DWORD) __attribute__ ((regparm (2)));
class _pinfo;
void __stdcall proc_terminate ();
void __stdcall sigproc_init ();
-void __stdcall sigproc_terminate ();
+void __stdcall sigproc_terminate (enum exit_states);
bool __stdcall pid_exists (pid_t) __attribute__ ((regparm(1)));
int __stdcall sig_send (_pinfo *, siginfo_t&, class _cygtls *tls = NULL) __attribute__ ((regparm (3)));
int __stdcall sig_send (_pinfo *, int) __attribute__ ((regparm (2)));
diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h
index 2bc40b1..960c6c4 100644
--- a/winsup/cygwin/winsup.h
+++ b/winsup/cygwin/winsup.h
@@ -193,10 +193,10 @@ enum exit_states
ES_THREADTERM,
ES_SIGNAL,
ES_CLOSEALL,
- ES_SIGPROCTERMINATE,
- ES_TITLE,
ES_HUP_PGRP,
ES_HUP_SID,
+ ES_SIGPROCTERMINATE,
+ ES_TITLE,
ES_TTY_TERMINATE,
ES_FINAL
};