OSDN Git Service

* exceptions.cc (_cygtls::interrupt_now): Revert to checking for "spinning"
authorcgf <cgf>
Sun, 1 Aug 2010 19:10:52 +0000 (19:10 +0000)
committercgf <cgf>
Sun, 1 Aug 2010 19:10:52 +0000 (19:10 +0000)
when choosing to defer signal.
(_cygtls::call_signal_handler): Grab func when we have the lock.
* gendef: Update copyright.
(__sigbe): Simplify slightly.
(_sigdelayed): Grab a lock before manipulating stuff.
(_cygtls::pop): Properly return popped value.
(stabilize_sig_stack): Set incyg when we have the lock.
* sigproc.cc: Update copyright.

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

index 1f581a9..e233be0 100644 (file)
@@ -1,3 +1,15 @@
+2010-08-01  Christopher Faylor  <me+cygwin@cgf.cx>
+
+       * exceptions.cc (_cygtls::interrupt_now): Revert to checking for
+       "spinning" when choosing to defer signal.
+       (_cygtls::call_signal_handler): Grab func when we have the lock.
+       * gendef: Update copyright.
+       (__sigbe): Simplify slightly.
+       (_sigdelayed): Grab a lock before manipulating stuff.
+       (_cygtls::pop): Properly return popped value.
+       (stabilize_sig_stack): Set incyg when we have the lock.
+       * sigproc.cc: Update copyright.
+
 2010-07-28  Christopher Faylor  <me+cygwin@cgf.cx>
 
        * cygthread.h (LPVOID_THREAD_START_ROUTINE): Define.
index 50ee795..a2afa5e 100644 (file)
@@ -778,7 +778,11 @@ _cygtls::interrupt_now (CONTEXT *cx, int sig, void *handler,
 {
   bool interrupted;
 
-  if (incyg || inside_kernel (cx))
+  /* Delay the interrupt if we are
+     1) somehow inside the DLL
+     2) in _sigfe (spinning is true) and about to enter cygwin DLL
+     3) in a Windows DLL.  */
+  if (incyg || spinning || inside_kernel (cx))
     interrupted = false;
   else
     {
@@ -1372,6 +1376,7 @@ _cygtls::call_signal_handler ()
       lock ();
       this_sa_flags = sa_flags;
       int thissig = sig;
+      void (*thisfunc) (int) = func;
 
       pop ();
       reset_signal_arrived ();
@@ -1382,13 +1387,13 @@ _cygtls::call_signal_handler ()
       incyg = 0;
       if (!(this_sa_flags & SA_SIGINFO))
        {
-         void (*sigfunc) (int) = func;
+         void (*sigfunc) (int) = thisfunc;
          sigfunc (thissig);
        }
       else
        {
          siginfo_t thissi = infodata;
-         void (*sigact) (int, siginfo_t *, void *) = (void (*) (int, siginfo_t *, void *)) func;
+         void (*sigact) (int, siginfo_t *, void *) = (void (*) (int, siginfo_t *, void *)) thisfunc;
          /* no ucontext_t information provided yet */
          sigact (thissig, &thissi, NULL);
        }
index 15d9f4c..e1fa0d9 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/perl
-# Copyright 2003, 2004, 2005, 2006, 2008 Red Hat, Inc.
+# Copyright 2003, 2004, 2005, 2006, 2008, 2009, 2010 Red Hat, Inc.
 #
 # This file is part of Cygwin.
 #
@@ -141,9 +141,8 @@ __sigfe:
 
        .global __sigbe
 __sigbe:                                               # return here after cygwin syscall
-       pushl   %edx
-       pushl   %ebx
        pushl   %eax                                    # don't clobber
+       pushl   %ebx                                    # tls pointer
 1:     movl    %fs:4,%ebx                              # address of bottom of tls
        movl    \$1,%eax                                # potential lock value
        xchgl   %eax,$tls::stacklock(%ebx)              # see if we can grab it
@@ -154,12 +153,10 @@ __sigbe:                                          # return here after cygwin syscall
        jmp     1b                                      #  and loop
 2:     movl    \$-4,%eax                               # now decrement aux stack
        xadd    %eax,$tls::stackptr(%ebx)               #  and get pointer
-       xorl    %edx,%edx
-       xchgl   %edx,-4(%eax)                           # get return address from signal stack
-       xchgl   %edx,8(%esp)                            # restore edx/real return address
+       movl    -4(%eax),%eax                           # get return address from signal stack
+       xchgl   %eax,4(%esp)                            # swap return address with saved eax
        decl    $tls::incyg(%ebx)
        decl    $tls::stacklock(%ebx)                   # release lock
-       popl    %eax
        popl    %ebx
        ret
 
@@ -175,7 +172,7 @@ _sigreturn:
        movl    %eax,$tls::spinning(%ebx)               # flag if we are waiting for lock
        testl   %eax,%eax                               # it will be zero
        jz      2f                                      #  if so
-       call    _yield                  # sleep
+       call    _yield                                  # sleep
        jmp     1b                                      #  and loop
 2:     popl    %edx                                    # saved errno
        testl   %edx,%edx                               # Is it < 0
@@ -211,7 +208,19 @@ _sigdelayed:
        pushl   %ebx
        pushl   %eax
        movl    %fs:4,%ebx
-       incl    $tls::incyg(%ebx)
+1:     movl    \$1,%eax
+       xchgl   %eax,$tls::stacklock(%ebx)
+       movl    %eax,$tls::spinning(%ebx) # flag if we are waiting for lock
+                                         # If %eax is 1 then someone else has
+                                         # the lock but we want to flag that
+                                         # we're waiting for it.  If %eax is 0
+                                         # then we're not spinning and 0 will
+                                         # reflect that.
+       testl   %eax,%eax
+       jz      2f
+       call    _yield
+       jmp     1b
+2:     incl    $tls::incyg(%ebx)
        pushl   $tls::saved_errno(%ebx) # saved errno
        call    _set_process_mask_delta
        pushl   %eax
@@ -225,21 +234,23 @@ _sigdelayed:
 
        call    _reset_signal_arrived\@0
        pushl   \$_sigreturn            # where to return
-       pushl   $tls::func(%ebx)        # signal func
+       pushl   $tls::func(%ebx)        # user-supplied signal func
        cmpl    \$0,$tls::threadkill(%ebx)#pthread_kill signal?
        jnz     4f                      # yes.  callee clears signal number
        movl    \$0,$tls::sig(%ebx)     # zero the signal number as a
                                        # flag to the signal handler thread
                                        # that it is ok to set up sigsave
 4:     decl    $tls::incyg(%ebx)
-       ret
+       decl    $tls::stacklock(%ebx)
+       ret                             # return via signal handler
 
-       .global __ZN7_cygtls3popEv
+       .global __ZN7_cygtls3popEv
 __ZN7_cygtls3popEv:
 1:     pushl   %ebx
        movl    %eax,%ebx                       # this
        movl    \$-4,%eax
        xadd    %eax,$tls::pstackptr(%ebx)
+       movl    -4(%eax),%eax
        popl    %ebx
        ret
 
@@ -269,7 +280,6 @@ __ZN7_cygtls6lockedEv:
        .extern __ZN7_cygtls19call_signal_handlerEv
 stabilize_sig_stack:
        movl    %fs:4,%ebx
-       incl    $tls::incyg(%ebx)
 1:     movl    \$1,%eax
        xchgl   %eax,$tls::stacklock(%ebx)
        movl    %eax,$tls::spinning(%ebx)               # flag if we are waiting for lock
@@ -277,7 +287,8 @@ stabilize_sig_stack:
        jz      2f
        call    _yield
        jmp     1b
-2:     cmpl    \$0,$tls::sig(%ebx)
+2:     incl    $tls::incyg(%ebx)
+       cmpl    \$0,$tls::sig(%ebx)
        jz      3f
        decl    $tls::stacklock(%ebx)                   # unlock
        movl    \$-$tls::sizeof__cygtls,%eax            # point to beginning
index 74e96ce..df79780 100644 (file)
@@ -1,7 +1,7 @@
 /* sigproc.cc: inter/intra signal and sub process handler
 
    Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-   2006, 2007, 2008 Red Hat, Inc.
+   2006, 2007, 2008, 2009, 2010 Red Hat, Inc.
 
    Written by Christopher Faylor