diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index fd17f338b..671ff0b8e 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,28 @@ +2004-02-01 Christopher Faylor + + * cygerrno.h (set_errno): Set global errno whenever setting thread + specific version. + * debug.cc (__set_errno): Ditto. + + * exceptions.cc (handle_sigsuspend): Remove spurious + sig_dispatch_pending call. + (set_signal_mask): When there seem to be pending signals to dispatch, + tell signal_dispatch_pending/sig_send not to specifically call any + handlers. + * sigproc.h (sig_dispatch_pending): Change declaration to void. + * sigproc.cc (sig_dispatch_pending): Change definition to void. Take + an argument to determine whether to tell sig_send to wait for handler + to be called. + * sigproc.cc (sig_send): Don't call signal handler when sig == + __SIGFLUSHFAST. + (wait_sig): Honor __SIGFLUSHFAST. Guard against sigpacket::process + nuking si_signo. + * sigproc.h (__SIGFLUSHFAST): Define new special signal. + (sig_dispatch_pending): Change declaration to void. Take optional + boolean argument. + + * fork.cc (vfork): Add debugging output. + 2004-01-26 Christopher Faylor * exceptions.cc (sig_handle_tty_stop): Avoid races by waiting for both diff --git a/winsup/cygwin/cygerrno.h b/winsup/cygwin/cygerrno.h index fb00f3f1d..12b6691b7 100644 --- a/winsup/cygwin/cygerrno.h +++ b/winsup/cygwin/cygerrno.h @@ -1,6 +1,6 @@ /* cygerrno.h: main Cygwin header file. - Copyright 2000, 2001, 2002, 2003 Red Hat, Inc. + Copyright 2000, 2001, 2002, 2003, 2004 Red Hat, Inc. This file is part of Cygwin. @@ -18,7 +18,7 @@ int __stdcall geterrno_from_win_error (DWORD code, int deferrno) __attribute__ ( #define __seterrno_from_win_error(val) seterrno_from_win_error (__FILE__, __LINE__, val) #ifndef DEBUGGING -#define set_errno(val) (errno = (val)) +#define set_errno(val) (errno = (val); _impure_ptr->_errno = (val)) #else int __stdcall __set_errno (const char *ln, int ln, int val) __attribute ((regparm(3))); #define set_errno(val) __set_errno (__PRETTY_FUNCTION__, __LINE__, (val)) diff --git a/winsup/cygwin/debug.cc b/winsup/cygwin/debug.cc index 2a6b86735..6ab63eb58 100644 --- a/winsup/cygwin/debug.cc +++ b/winsup/cygwin/debug.cc @@ -237,6 +237,7 @@ int __stdcall __set_errno (const char *func, int ln, int val) { debug_printf ("%s:%d val %d", func, ln, val); + _impure_ptr->_errno = val; return errno = val; } #endif /*DEBUGGING*/ diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 11088fcfd..4983a2ede 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -1,6 +1,6 @@ /* exceptions.cc - Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc. + Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc. This file is part of Cygwin. @@ -591,11 +591,10 @@ stack (void) int __stdcall handle_sigsuspend (sigset_t tempmask) { - sig_dispatch_pending (); sigset_t oldmask = myself->getsigmask (); // Remember for restoration - set_signal_mask (tempmask &= ~SIG_NONMASKABLE, oldmask);// Let signals we're - // interested in through. + // Let signals we're interested in through. + set_signal_mask (tempmask &= ~SIG_NONMASKABLE, oldmask); sigproc_printf ("oldmask %p, newmask %p", oldmask, tempmask); pthread_testcancel (); @@ -925,11 +924,11 @@ set_signal_mask (sigset_t newmask, sigset_t oldmask) sigproc_printf ("oldmask %p, newmask %p, mask_bits %p", oldmask, newmask, mask_bits); myself->setsigmask (newmask); // Set a new mask - mask_sync->release (); if (mask_bits) - sig_dispatch_pending (); + sig_dispatch_pending (true); else sigproc_printf ("not calling sig_dispatch_pending"); + mask_sync->release (); return; } diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index 2471ad225..681675a62 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -698,6 +698,7 @@ extern "C" int vfork () { #ifndef NEWVFORK + debug_printf ("stub called"); return fork (); #else vfork_save *vf = get_vfork_val (); diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 3be7f8954..327382e8c 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -63,7 +63,7 @@ public: sigpacket *next (); sigpacket *save () const {return curr;} void restore (sigpacket *saved) {curr = saved;} - friend int __stdcall sig_dispatch_pending (); + friend void __stdcall sig_dispatch_pending (bool); }; static pending_signals sigqueue; @@ -431,8 +431,7 @@ proc_subproc (DWORD what, DWORD val) scan_wait: /* Scan the linked list of wait()ing threads. If a wait's parameters - * match this pid, then activate it. - */ + match this pid, then activate it. */ for (w = &waitq_head; w->next != NULL; w = w->next) { if ((potential_match = checkstate (w)) > 0) @@ -567,8 +566,8 @@ sigpending (sigset_t *mask) } /* Force the wait_sig thread to wake up and scan for pending signals */ -int __stdcall -sig_dispatch_pending () +void __stdcall +sig_dispatch_pending (bool fast) { if (exit_state || GetCurrentThreadId () == sigtid || !sigqueue.start.next) { @@ -576,14 +575,13 @@ sig_dispatch_pending () sigproc_printf ("exit_state %d, cur thread id %p, sigtid %p, sigqueue.start.next %p", exit_state, GetCurrentThreadId (), sigtid, sigqueue.start.next); #endif - return 0; + return; } #ifdef DEBUGGING sigproc_printf ("flushing"); #endif - (void) sig_send (myself, __SIGFLUSH); - return call_signal_handler_now (); + (void) sig_send (myself, fast ? __SIGFLUSHFAST : __SIGFLUSH); } /* Message initialization. Called from dll_crt0_1 @@ -800,6 +798,12 @@ sig_send (_pinfo *p, siginfo_t& si, _threadinfo *tls) ForceCloseHandle (sendsig); } + if (pack.wakeup) + { + ForceCloseHandle (pack.wakeup); + pack.wakeup = NULL; + } + if (rc == WAIT_OBJECT_0) rc = 0; // Successful exit else @@ -811,13 +815,12 @@ sig_send (_pinfo *p, siginfo_t& si, _threadinfo *tls) rc = -1; } - if (wait_for_completion) + if (wait_for_completion && si.si_signo != __SIGFLUSHFAST) call_signal_handler_now (); out: if (pack.wakeup) ForceCloseHandle (pack.wakeup); - if (si.si_signo != __SIGPENDING) /* nothing */; else if (!rc) @@ -1164,6 +1167,7 @@ wait_sig (VOID *self) *pack.mask |= bit; break; case __SIGFLUSH: + case __SIGFLUSHFAST: sigqueue.reset (); while ((q = sigqueue.next ())) if (q->si.si_signo == __SIGDELETE || q->process () > 0) @@ -1174,6 +1178,7 @@ wait_sig (VOID *self) sig_clear (-pack.si.si_signo); else { + int sig = pack.si.si_signo; int sigres = pack.process (); if (sigres <= 0) { @@ -1183,7 +1188,7 @@ wait_sig (VOID *self) #endif sigqueue.add (pack); // FIXME: Shouldn't add this in !sh condition } - if (pack.si.si_signo == SIGCHLD) + if (sig == SIGCHLD) proc_subproc (PROC_CLEARWAIT, 0); } break; diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h index b37b91ed9..e9c762112 100644 --- a/winsup/cygwin/sigproc.h +++ b/winsup/cygwin/sigproc.h @@ -1,6 +1,6 @@ /* sigproc.h - Copyright 1997, 1998, 2000, 2001, 2002, 2003 Red Hat, Inc. + Copyright 1997, 1998, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc. This file is part of Cygwin. @@ -23,7 +23,8 @@ enum __SIGSTRACE = -(NSIG + 2), __SIGCOMMUNE = -(NSIG + 3), __SIGPENDING = -(NSIG + 4), - __SIGDELETE = -(NSIG + 5) + __SIGDELETE = -(NSIG + 5), + __SIGFLUSHFAST = -(NSIG + 6) }; #endif @@ -67,7 +68,7 @@ extern HANDLE signal_arrived; extern HANDLE sigCONT; bool __stdcall my_parent_is_alive (); -int __stdcall sig_dispatch_pending (); +void __stdcall sig_dispatch_pending (bool fast = false); #ifdef _PINFO_H extern "C" void __stdcall set_signal_mask (sigset_t newmask, sigset_t = myself->getsigmask ()); #endif