diff options
author | Christopher Faylor <me@cgf.cx> | 2005-09-14 14:00:07 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2005-09-14 14:00:07 +0000 |
commit | a611ae50d5c1106988df7ec8b053efc332e35ae3 (patch) | |
tree | 0057df8d08fd439ed9bcfb06bd07538c6f2f9d6e | |
parent | 67483cb2cdee37aa435fd108cea5310a873925a3 (diff) | |
download | newlib-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/ChangeLog | 30 | ||||
-rw-r--r-- | winsup/cygwin/cygtls.h | 1 | ||||
-rw-r--r-- | winsup/cygwin/dcrt0.cc | 24 | ||||
-rw-r--r-- | winsup/cygwin/exceptions.cc | 6 | ||||
-rw-r--r-- | winsup/cygwin/pinfo.cc | 12 | ||||
-rw-r--r-- | winsup/cygwin/sigproc.cc | 42 | ||||
-rw-r--r-- | winsup/cygwin/sigproc.h | 2 | ||||
-rw-r--r-- | winsup/cygwin/winsup.h | 4 |
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 }; |