From fc0e4fa09eac94837c7b3c831c8088de46f406e7 Mon Sep 17 00:00:00 2001 From: cgf Date: Sun, 1 Aug 2010 19:10:52 +0000 Subject: [PATCH] * 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. --- winsup/cygwin/ChangeLog | 12 ++++++++++++ winsup/cygwin/exceptions.cc | 11 ++++++++--- winsup/cygwin/gendef | 39 +++++++++++++++++++++++++-------------- winsup/cygwin/sigproc.cc | 2 +- 4 files changed, 46 insertions(+), 18 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 1f581a9759..e233be0de7 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,15 @@ +2010-08-01 Christopher Faylor + + * 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 * cygthread.h (LPVOID_THREAD_START_ROUTINE): Define. diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 50ee795126..a2afa5e0fd 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -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); } diff --git a/winsup/cygwin/gendef b/winsup/cygwin/gendef index 15d9f4ceee..e1fa0d9e44 100755 --- a/winsup/cygwin/gendef +++ b/winsup/cygwin/gendef @@ -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 diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 74e96ce30b..df797808e6 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -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 -- 2.11.0