* 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.
This commit is contained in:
Christopher Faylor 2004-02-01 18:29:12 +00:00
parent f6565cd1a6
commit 9e1ad59de6
7 changed files with 54 additions and 22 deletions

View File

@ -1,3 +1,28 @@
2004-02-01 Christopher Faylor <cgf@redhat.com>
* 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 <cgf@redhat.com>
* exceptions.cc (sig_handle_tty_stop): Avoid races by waiting for both

View File

@ -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))

View File

@ -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*/

View File

@ -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;
}

View File

@ -698,6 +698,7 @@ extern "C" int
vfork ()
{
#ifndef NEWVFORK
debug_printf ("stub called");
return fork ();
#else
vfork_save *vf = get_vfork_val ();

View File

@ -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;

View File

@ -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