OSDN Git Service

* exceptions.cc (handle_sigsuspend): Just sleep forever if called from non-main
authorcgf <cgf>
Thu, 25 Aug 2005 03:12:47 +0000 (03:12 +0000)
committercgf <cgf>
Thu, 25 Aug 2005 03:12:47 +0000 (03:12 +0000)
thread.
(sigpacket:process): Simplify logic which determines when and how a signal is
masked.  Don't trigger sigwait if there is a signal handler.
* sigproc.cc (wait_sig): Update comment.  Try to process a signal which is in
the queue if it isn't queued for the target thread (this is still not right).

winsup/cygwin/ChangeLog
winsup/cygwin/exceptions.cc
winsup/cygwin/sigproc.cc

index 361c01c..45c462a 100644 (file)
@@ -1,5 +1,15 @@
 2005-08-24  Christopher Faylor  <cgf@timesys.com>
 
+       * exceptions.cc (handle_sigsuspend): Just sleep forever if called from
+       non-main thread.
+       (sigpacket:process): Simplify logic which determines when and how a
+       signal is masked.  Don't trigger sigwait if there is a signal handler.
+       * sigproc.cc (wait_sig): Update comment.  Try to process a signal which
+       is in the queue if it isn't queued for the target thread (this is still
+       not right).
+
+2005-08-24  Christopher Faylor  <cgf@timesys.com>
+
        * spawn.cc (perhaps_suffix): Record errno-type error value in third
        argument.
        (find_exec): On error, set errno returned from perhaps_suffix.
index 9ae77f8..e75ee61 100644 (file)
@@ -590,6 +590,8 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *)
 int __stdcall
 handle_sigsuspend (sigset_t tempmask)
 {
+  if (&_my_tls != _main_tls)
+    Sleep (INFINITE);
   sigset_t oldmask = myself->getsigmask ();    // Remember for restoration
 
   set_signal_mask (tempmask, myself->getsigmask ());
@@ -911,6 +913,7 @@ extern "C" void __stdcall
 set_process_mask (sigset_t newmask)
 {
   set_signal_mask (newmask, myself->getsigmask ());
+sigproc_printf ("mask now %p\n", myself->getsigmask ());
 }
 
 extern "C" int
@@ -1014,9 +1017,12 @@ sigpacket::process ()
 
   myself->rusage_self.ru_nsignals++;
 
+  bool masked;
+  void *handler = (void *) thissig.sa_handler;
+
   if (si.si_signo == SIGKILL)
     goto exit_sig;
-  if ( si.si_signo == SIGSTOP)
+  if (si.si_signo == SIGSTOP)
     {
       sig_clear (SIGCONT);
       if (!tls)
@@ -1024,35 +1030,34 @@ sigpacket::process ()
       goto stop;
     }
 
-  bool masked;
-  bool special_case;
   bool insigwait_mask;
-  insigwait_mask = masked = false;
-  if (special_case = (/*VFORKPID || */ISSTATE (myself, PID_STOPPED)))
-    /* nothing to do */;
-  else if (tls && sigismember (&tls->sigwait_mask, si.si_signo))
-    insigwait_mask = true;
-  else if (!tls && (tls = _cygtls::find_tls (si.si_signo)))
-    insigwait_mask = true;
-  else if (!(masked = sigismember (mask, si.si_signo)) && tls)
-    masked  = sigismember (&tls->sigmask, si.si_signo);
+  if ((masked = ISSTATE (myself, PID_STOPPED)))
+    insigwait_mask = false;
+  else if (!tls)
+    insigwait_mask = !handler && (tls = _cygtls::find_tls (si.si_signo));
+  else
+    insigwait_mask = sigismember (&tls->sigwait_mask, si.si_signo);
 
   if (insigwait_mask)
     goto thread_specific;
 
+  if (masked)
+    /* nothing to do */;
+  else if (sigismember (mask, si.si_signo))
+    masked = true;
+  else if (tls)
+    masked  = sigismember (&tls->sigmask, si.si_signo);
+
   if (!tls)
     tls = _main_tls;
 
-  if (special_case || masked)
+  if (masked)
     {
       sigproc_printf ("signal %d blocked", si.si_signo);
       rc = -1;
       goto done;
     }
 
-  void *handler;
-  handler = (void *) thissig.sa_handler;
-
   /* Clear pending SIGCONT on stop signals */
   if (si.si_signo == SIGTSTP || si.si_signo == SIGTTIN || si.si_signo == SIGTTOU)
     sig_clear (SIGCONT);
index 2bb9d4e..382b226 100644 (file)
@@ -1097,9 +1097,10 @@ wait_sig (VOID *self)
          else
            {
              int sig = pack.si.si_signo;
-             // FIXME: Not quite right when taking threads into consideration.
-             // Do we need a per-thread queue?
-             if (sigq.sigs[sig].si.si_signo)
+             // FIXME: REALLY not right when taking threads into consideration.
+             // We need a per-thread queue since each thread can have its own
+             // list of blocked signals.  CGF 2005-08-24
+             if (sigq.sigs[sig].si.si_signo && sigq.sigs[sig].tls == pack.tls)
                sigproc_printf ("sig %d already queued", pack.si.si_signo);
              else
                {