summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog25
-rw-r--r--winsup/cygwin/cygerrno.h4
-rw-r--r--winsup/cygwin/debug.cc1
-rw-r--r--winsup/cygwin/exceptions.cc11
-rw-r--r--winsup/cygwin/fork.cc1
-rw-r--r--winsup/cygwin/sigproc.cc27
-rw-r--r--winsup/cygwin/sigproc.h7
7 files changed, 54 insertions, 22 deletions
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 <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
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