]> sourceware.org Git - newlib-cygwin.git/commitdiff
* exceptions.cc (sig_handle_tty_stop): Avoid races by waiting for both
authorChristopher Faylor <me@cgf.cx>
Mon, 26 Jan 2004 22:25:57 +0000 (22:25 +0000)
committerChristopher Faylor <me@cgf.cx>
Mon, 26 Jan 2004 22:25:57 +0000 (22:25 +0000)
signal_arrived and for sigCONT.
(sigpacket::process): Enforce sending of both signal_arrived and sigCONT, where
appropriate.
* gendef (sigreturn): Save tls pointer in ebx so that it can jump into
sigdelayed and use the same register.

winsup/cygwin/ChangeLog
winsup/cygwin/exceptions.cc
winsup/cygwin/gendef

index bfc201968f7a85d0c9e5c908a927350db9857c6d..fd17f338b3d7fbd6035419bc2bd59ec87a9834d0 100644 (file)
@@ -1,3 +1,12 @@
+2004-01-26  Christopher Faylor  <cgf@redhat.com>
+
+       * exceptions.cc (sig_handle_tty_stop): Avoid races by waiting for both
+       signal_arrived and for sigCONT.
+       (sigpacket::process): Enforce sending of both signal_arrived and
+       sigCONT, where appropriate.
+       * gendef (sigreturn): Save tls pointer in ebx so that it can jump into
+       sigdelayed and use the same register.
+
 2004-01-26  Christopher Faylor  <cgf@redhat.com>
 
        * cygtls.cc (_threadinfo::init_thread): Add more local reent stdio
index db70fa51dbd7ec2a58f215b4aa3322c74b3dacc7..11088fcfd1bccfbf9becf380d7e6883f7c9b83ab 100644 (file)
@@ -644,8 +644,19 @@ sig_handle_tty_stop (int sig)
     }
   sigproc_printf ("process %d stopped by signal %d, myself->ppid_handle %p",
                  myself->pid, sig, myself->ppid_handle);
-  if (WaitForSingleObject (sigCONT, INFINITE) != WAIT_OBJECT_0)
-    api_fatal ("WaitSingleObject failed, %E");
+  HANDLE w4[2];
+  w4[0] = sigCONT;
+  w4[1] = signal_arrived;
+  switch (WaitForMultipleObjects (2, w4, TRUE, INFINITE))
+    {
+    case WAIT_OBJECT_0:
+    case WAIT_OBJECT_0 + 1:
+      reset_signal_arrived ();
+      break;
+    default:
+      api_fatal ("WaitSingleObject failed, %E");
+      break;
+    }
   return;
 }
 }
@@ -925,9 +936,12 @@ set_signal_mask (sigset_t newmask, sigset_t oldmask)
 int __stdcall
 sigpacket::process ()
 {
-  if (si.si_signo == SIGCONT)
+  DWORD continue_now;
+  if (si.si_signo != SIGCONT)
+    continue_now = false;
+  else
     {
-      DWORD stopped = myself->process_state & PID_STOPPED;
+      continue_now = myself->process_state & PID_STOPPED;
       myself->stopsig = 0;
       myself->process_state &= ~PID_STOPPED;
       /* Clear pending stop signals */
@@ -935,8 +949,6 @@ sigpacket::process ()
       sig_clear (SIGTSTP);
       sig_clear (SIGTTIN);
       sig_clear (SIGTTOU);
-      if (stopped)
-       SetEvent (sigCONT);
     }
 
   int rc = 1;
@@ -1001,6 +1013,8 @@ sigpacket::process ()
          || si.si_signo == SIGURG)
        {
          sigproc_printf ("default signal %d ignored", si.si_signo);
+         if (continue_now)
+           SetEvent (signal_arrived);
          goto done;
        }
 
@@ -1037,6 +1051,8 @@ dosig1:
   rc = setup_handler (si.si_signo, handler, thissig, tls);
 
 done:
+  if (continue_now)
+    SetEvent (sigCONT);
   sigproc_printf ("returning %d", rc);
   return rc;
 
index 5addf91e2b6a41c06d75ec4f80989c29f4f6d8e3..d317eeacd1eb1c424a160779300a4f4a7cc630ed 100755 (executable)
@@ -127,15 +127,15 @@ _sigreturn:
        addl    \$4,%esp                        # Remove argument
        call    _set_process_mask\@4
 
-       movl    %fs:4,%eax
+       movl    %fs:4,%ebx
 
-       cmpl    \$0,$tls::sig(%eax)     # Did a signal come in?
+       cmpl    \$0,$tls::sig(%ebx)     # Did a signal come in?
        jnz     3f                      # Yes, if non-zero
 
 1:     popl    %edx                    # saved errno
        testl   %edx,%edx               # Is it < 0
        jl      2f                      # yup.  ignore it
-       movl    $tls::errno_addr(%eax),%eax
+       movl    $tls::errno_addr(%ebx),%eax
        movl    %edx,(%eax)
 2:     popl    %eax
        popl    %ebx
This page took 0.033386 seconds and 5 git commands to generate.