From 9a4d574b8d4550f53036dced342022b64e508abf Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Fri, 28 Nov 2003 20:55:59 +0000 Subject: 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. --- winsup/cygwin/sigproc.cc | 123 ++++++++++++++++++----------------------------- 1 file changed, 46 insertions(+), 77 deletions(-) (limited to 'winsup/cygwin/sigproc.cc') 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 #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; -} -} -- cgit v1.2.3