diff options
author | Christopher Faylor <me@cgf.cx> | 2003-11-28 23:55:59 +0300 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2003-11-28 23:55:59 +0300 |
commit | 9a4d574b8d4550f53036dced342022b64e508abf (patch) | |
tree | 79d7ab65654ff5cb2fd2c0c035ac2b98deb1fcc2 /winsup/cygwin/sigproc.cc | |
parent | ffe006384344b5d2a86e6bedad96725391cfe88e (diff) |
Eliminate use of sigframe and sigthread throughout.
* Makefile.in (DLL_OFILES): Add sigfe.o. Remove reliance on cygwin.def from
cygwin0.dll dependency since dependence on sigfe.o implies that. Generate def
file on the fly using 'gendef'.
* configure.in: Don't auto-generate cygwin.def.
* configure: Regenerate.
* cygwin.din: Add SIGFE stuff where appropriate.
* dcrt0.cc (dll_crt0_1): Initialize cygwin tls early in process startup. Set
_main_tls to address of the main thread's cygwin tls.
* debug.h: Remove now unneeded WFSO and WFMO declarations.
* exceptions.cc (_last_thread): Define.
(set_thread_state_for_signals): New function.
(reset_thread_exception_for_signals): Ditto.
(init_thread_for_signals): Ditto.
(delete_thread_for_signals): Ditto.
(capture_thread_for_signals): Ditto.
(handle_exceptions): Set return address explicitly for exceptions prior to
calling sig_send.
(interrupt_on_return): Eliminate.
(setup_handler): Add preliminary implementation for dealing with
thread-specific signals by querying _main_tls.
(signal_exit): Use cygthread::main_thread_id instead of mainthread.id.
(call_signal_handler_now): For now, just handle the main thread.
* fork.cc (vfork): Save and restore main _my_tls.
* gendef: New file. Generates def file and sigfe.s file.
* gentls_offsets: New file. Generates offsets for perl to use in sigfe.s.
* how-signals-work.txt: Mention that info is obsolete.
* init.cc (dll_entry): Initialize cygwin tls storage here.
* miscfuncs.cc (low_priority_sleep): Make a C function for easier calling from
asm.
* perthread.h (vfork_save::tls): New element.
* signal.cc (nanosleep): Replace previous use of
sigframe.call_signal_handler_now with straight call to call_signal_handler_now.
(abort): Ditto.
* syscalls.cc (readv): Ditto.
* termios.cc (tcsetattr): Ditto.
* wait.cc (wait4): Ditto.
* sigproc.cc (sig_dispatch_pending): Ditto.
(sig_send): Ditto.
* sigproc.h: Declare call_signal_handler_now.
* thread.cc (pthread::thread_init_wrapper): Initialize cygwin tls. Remove
obsolete and unworking signal stuff.
* thread.h (verifyable_object::sigs): Eliminate.
(verifyable_object::sigmask): Eliminate.
(verifyable_object::sigtodo): Eliminate.
(verifyable_object::exit): Make attribute noreturn.
(verifyable_object::thread_init_wrapper): Ditto.
(pthread_null::exit): Ditto.
* winbase.h (__stackbase): Always define.
* winsup.h (low_priority_sleep): Declare as a "C" function.
* include/cygwin/version.h: Bump API version to reflect sigwait export.
* include/sys/queue.h: Protect SLIST_ENTRY from previous declaration.
* signal.cc (sigwait): Implement.
* select.cc (fhandler_base::ready_for_read): Add debugging output.
* devices.h: Define more device pointers via their storage.
* devices.in: Don't parse things like /dev/inet/tcp, as they really have no
meaning.
* devices.cc: Regenerate.
* gendevices: Set proper protection for output file.
* cygtls.h: New file.
* gendef: New file.
* gentls_offsets: New file.
* tlsoffsets.h: New file. Autogenerated.
* config/i386/longjmp.c: Remove. File subsumed by gendef output.
* config/i386/makefrag: Remove obsolete file.
* fhandler.cc: Remove spurious access_worker declaration.
* spawn.cc (spawnve): Make debugging output more accurate.
* cygwin-gperf: Remove.
* devices.cc: Remove.
Diffstat (limited to 'winsup/cygwin/sigproc.cc')
-rw-r--r-- | winsup/cygwin/sigproc.cc | 123 |
1 files changed, 46 insertions, 77 deletions
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index cecbe70c3..984000478 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -20,6 +20,7 @@ details. */ #include <sys/signal.h> #include "cygerrno.h" #include "sync.h" +#include "cygtls.h" #include "sigproc.h" #include "pinfo.h" #include "security.h" @@ -37,10 +38,6 @@ details. */ */ #define WSSC 60000 // Wait for signal completion #define WPSP 40000 // Wait for proc_subproc mutex -#define WSPX 20000 // Wait for wait_sig to terminate -#define WWSP 20000 // Wait for wait_subproc to terminate - -#define TOTSIGS (NSIG + __SIGOFFSET) #define wake_wait_subproc() SetEvent (events[0]) @@ -48,9 +45,11 @@ details. */ #define NZOMBIES 256 -class sigelem +struct sigelem { int sig; + int pid; + _threadinfo *tls; class sigelem *next; friend class pending_signals; friend int __stdcall sig_dispatch_pending (); @@ -66,9 +65,9 @@ class pending_signals int empty; public: void reset () {curr = &start; prev = &start;} - void add (int sig); + void add (int sig, int pid, _threadinfo *tls); void del (); - int next (); + sigelem *next (); friend int __stdcall sig_dispatch_pending (); }; @@ -78,6 +77,7 @@ struct sigpacket pid_t pid; HANDLE wakeup; sigset_t *mask; + _threadinfo *tls; }; static pending_signals sigqueue; @@ -112,10 +112,6 @@ int __sp_ln; char NO_COPY myself_nowait_dummy[1] = {'0'};// Flag to sig_send that signal goes to // current process but no wait is required -char NO_COPY myself_nowait_nonmain_dummy[1] = {'1'};// Flag to sig_send that signal goes to - // current process but no wait is required - // if this is the main thread. - HANDLE NO_COPY signal_arrived; // Event signaled when a signal has // resulted in a user-specified // function call @@ -244,7 +240,7 @@ get_proc_lock (DWORD what, DWORD val) static BOOL __stdcall proc_can_be_signalled (_pinfo *p) { - if (p == myself_nowait || p == myself_nowait_nonmain || p == myself) + if (p == myself_nowait || p == myself) { assert (!wait_sig_inited); return 1; @@ -549,10 +545,10 @@ sig_clear (int target_sig) sig_send (myself, -target_sig); else { - int sig; sigqueue.reset (); - while ((sig = sigqueue.next ())) - if (sig == target_sig) + sigelem *q; + while ((q = sigqueue.next ())) + if (q->sig == target_sig) { sigqueue.del (); break; @@ -578,9 +574,8 @@ sig_dispatch_pending () if (exit_state || GetCurrentThreadId () == sigtid || !sigqueue.start.next) return 0; - sigframe thisframe (mainthread); (void) sig_send (myself, __SIGFLUSH); - return thisframe.call_signal_handler (); + return call_signal_handler_now (); } /* Message initialization. Called from dll_crt0_1 @@ -654,18 +649,15 @@ sigproc_terminate (void) * completed before returning. */ int __stdcall -sig_send (_pinfo *p, int sig, DWORD ebp, bool exception) +sig_send (_pinfo *p, int sig, void *tls) { int rc = 1; - DWORD tid = GetCurrentThreadId (); BOOL its_me; HANDLE sendsig; - bool wait_for_completion; - sigframe thisframe; sigpacket pack; - if (p == myself_nowait_nonmain) - p = (tid == mainthread.id) ? (_pinfo *) myself : myself_nowait; + bool wait_for_completion; + // FIXMENOW: Avoid using main thread's completion event! if (!(its_me = (p == NULL || p == myself || p == myself_nowait))) wait_for_completion = false; else @@ -674,7 +666,7 @@ sig_send (_pinfo *p, int sig, DWORD ebp, bool exception) goto out; // Either exiting or not yet initializing if (wait_sig_inited) wait_for_sigthread (); - wait_for_completion = p != myself_nowait; + wait_for_completion = p != myself_nowait && _my_tls.isinitialized (); p = myself; } @@ -695,11 +687,7 @@ sig_send (_pinfo *p, int sig, DWORD ebp, bool exception) { sendsig = myself->sendsig; if (wait_for_completion) - { - if (tid == mainthread.id) - thisframe.init (mainthread, ebp, exception); - pack.wakeup = sigcomplete_main; - } + pack.wakeup = sigcomplete_main; } else { @@ -735,6 +723,7 @@ sig_send (_pinfo *p, int sig, DWORD ebp, bool exception) pack.sig = sig; pack.pid = myself->pid; + pack.tls = (_threadinfo *) tls; DWORD nb; if (!WriteFile (sendsig, &pack, sizeof (pack), &nb, NULL) || nb != sizeof (pack)) { @@ -790,7 +779,7 @@ sig_send (_pinfo *p, int sig, DWORD ebp, bool exception) } if (wait_for_completion) - thisframe.call_signal_handler (); + call_signal_handler_now (); out: if (sig != __SIGPENDING) @@ -995,7 +984,7 @@ talktome () has been handled, as per POSIX. */ void -pending_signals::add (int sig) +pending_signals::add (int sig, int pid, _threadinfo *tls) { sigelem *se; for (se = start.next; se; se = se->next) @@ -1007,6 +996,8 @@ pending_signals::add (int sig) se = sigs + empty; se->sig = sig; se->next = NULL; + se->tls = tls; + se->pid = pid; if (end) end->next = se; end = se; @@ -1030,16 +1021,16 @@ pending_signals::del () curr = next; } -int +sigelem * pending_signals::next () { - int sig; + sigelem *res; prev = curr; if (!curr || !(curr = curr->next)) - sig = 0; + res = NULL; else - sig = curr->sig; - return sig; + res = curr; + return res; } /* Process signals by waiting for signal data to arrive in a pipe. @@ -1105,7 +1096,12 @@ wait_sig (VOID *self) } if (!pack.sig) - continue; /* Just checking to see if we exist */ + { +#ifdef DEBUGGING + system_printf ("zero signal?"); +#endif + continue; + } sigset_t dummy_mask; if (!pack.mask) @@ -1114,40 +1110,39 @@ wait_sig (VOID *self) pack.mask = &dummy_mask; } + sigelem *q; switch (pack.sig) { case __SIGCOMMUNE: talktome (); - continue; + break; case __SIGSTRACE: strace.hello (); - continue; + break; case __SIGPENDING: *pack.mask = 0; unsigned bit; sigqueue.reset (); - while ((pack.sig = sigqueue.next ())) - if (myself->getsigmask () & (bit = SIGTOMASK (pack.sig))) + while ((q = sigqueue.next ())) + if (myself->getsigmask () & (bit = SIGTOMASK (q->sig))) *pack.mask |= bit; break; + case __SIGFLUSH: + sigqueue.reset (); + while ((q = sigqueue.next ())) + if (sig_handle (q->sig, *pack.mask, q->pid, q->tls) > 0) + sigqueue.del (); + break; default: if (pack.sig < 0) sig_clear (-pack.sig); else { - int sh; - for (int i = 0; !(sh = sig_handle (pack.sig, *pack.mask)) && i < 100 ; i++) - low_priority_sleep (0); // hopefully a temporary condition - if (sh <= 0) - sigqueue.add (pack.sig); // FIXME: Shouldn't add this in !sh condition + if (sig_handle (pack.sig, *pack.mask, pack.pid, pack.tls) <= 0) + sigqueue.add (pack.sig, pack.pid, pack.tls);// FIXME: Shouldn't add this in !sh condition if (pack.sig == SIGCHLD) proc_subproc (PROC_CLEARWAIT, 0); } - case __SIGFLUSH: - sigqueue.reset (); - while ((pack.sig = sigqueue.next ())) - if (sig_handle (pack.sig, *pack.mask) > 0) - sigqueue.del (); break; } if (pack.wakeup) @@ -1231,29 +1226,3 @@ wait_subproc (VOID *) sigproc_printf ("done"); ExitThread (0); } - -extern "C" { -/* Provide a stack frame when calling WaitFor* functions */ - -#undef WaitForSingleObject - -DWORD __stdcall -WFSO (HANDLE hHandle, DWORD dwMilliseconds) -{ - DWORD ret; - sigframe thisframe (mainthread); - ret = WaitForSingleObject (hHandle, dwMilliseconds); - return ret; -} - -#undef WaitForMultipleObjects - -DWORD __stdcall -WFMO (DWORD nCount, CONST HANDLE *lpHandles, BOOL fWaitAll, DWORD dwMilliseconds) -{ - DWORD ret; - sigframe thisframe (mainthread); - ret = WaitForMultipleObjects (nCount, lpHandles, fWaitAll, dwMilliseconds); - return ret; -} -} |