From 5fb0fe79eb76f59ac5d88e15c38b6e7bc63f9c91 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Tue, 9 Mar 2004 01:24:08 +0000 Subject: [PATCH] * exceptions.cc (setup_handler): Avoid suspending a thread if it in a cygwin function, in an exception, spinning, or locked. * gendef (_sigfe): Move incyg setting earlier. (sigreturn): Set incyg flag to avoid interrupting called cygwin functions. (sigdelayed): Ditto. (stabilize_sig_stack): Ditto. * sigproc.cc (proc_subproc): Don't restore process lock early in exec case. * cygtls.h: Reorganize fields in _cygtls slightly. * tlsoffsets.h: Regenerate. --- winsup/cygwin/ChangeLog | 18 +++++++++++++++++- winsup/cygwin/cygtls.h | 4 ++-- winsup/cygwin/exceptions.cc | 4 ++-- winsup/cygwin/gendef | 34 ++++++++++++++++++++-------------- winsup/cygwin/sigproc.cc | 1 - winsup/cygwin/tlsoffsets.h | 16 ++++++++-------- 6 files changed, 49 insertions(+), 28 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index c6d48b9e2..57a04aa4d 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,19 @@ +2004-03-08 Christopher Faylor + + * exceptions.cc (setup_handler): Avoid suspending a thread if it in a + cygwin function, in an exception, spinning, or locked. + * gendef (_sigfe): Move incyg setting earlier. + (sigreturn): Set incyg flag to avoid interrupting called cygwin + functions. + (sigdelayed): Ditto. + (stabilize_sig_stack): Ditto. + + * sigproc.cc (proc_subproc): Don't restore process lock early in exec + case. + + * cygtls.h: Reorganize fields in _cygtls slightly. + * tlsoffsets.h: Regenerate. + 2004-03-06 Christopher Faylor * fork.cc (fork_parent): Save parent pid in a temporary variable since @@ -148,7 +164,7 @@ feedback. (semaphore::wait): Return return value from semaphore::_wait. * thread.h (WAIT_SIGNALED): New definition. - (pthread::cancelable_wait): Change declaration. Define do_sig_wait + (pthread::cancelable_wait): Change declaration. Define do_sig_wait as false by default to not interfere with existing calls accidentally. (semaphore::_wait): Declare int. diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h index 5e2576635..a79f34803 100644 --- a/winsup/cygwin/cygtls.h +++ b/winsup/cygwin/cygtls.h @@ -111,9 +111,9 @@ struct _cygtls struct _cygtls *prev, *next; __stack_t *stackptr; int sig; - unsigned stacklock; - unsigned spinning; unsigned incyg; + unsigned spinning; + unsigned stacklock; __stack_t stack[TLS_STACK_SIZE]; unsigned padding[0]; diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 086ced32b..b99ffe4df 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -786,12 +786,12 @@ setup_handler (int sig, void *handler, struct sigaction& siga, _cygtls *tls) #endif res = SuspendThread (hth); /* Just set pending if thread is already suspended */ - if (res || tls->incyg) + if (res) { (void) ResumeThread (hth); break; } - if (!tls->locked () && !tls->spinning) + if (!tls->incyg && !tls->in_exception () && !tls->spinning && !tls->locked ()) { cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; if (!GetThreadContext (hth, &cx)) diff --git a/winsup/cygwin/gendef b/winsup/cygwin/gendef index c126fc03f..44679296f 100755 --- a/winsup/cygwin/gendef +++ b/winsup/cygwin/gendef @@ -92,6 +92,7 @@ __sigfe: pushl %ebx pushl %edx 1: movl %fs:4,%edx # location of bottom of stack + incl $tls::incyg(%edx) movl \$1,%eax # potential lock value lock xchgl %eax,$tls::stacklock(%edx) # see if we can grab it movl %eax,$tls::spinning(%edx) # flag if we are waiting for lock @@ -100,8 +101,7 @@ __sigfe: xorl %eax,%eax # nope. It was not zero call _low_priority_sleep # should be a short-time thing, so jmp 1b # sleep and loop -2: incl $tls::incyg(%edx) - movl \$4,%eax # have the lock, now increment the +2: movl \$4,%eax # have the lock, now increment the xadd %eax,$tls::stackptr(%edx) # stack pointer and get pointer leal __sigbe,%ebx # new place to return to xchgl %ebx,12(%esp) # exchange with real return value @@ -140,29 +140,31 @@ __sigbe: .global _sigreturn .stabs "sigreturn:F(0,1)",36,0,0,_sigreturn _sigreturn: + movl %fs:4,%ebx + incl $tls::incyg(%ebx) addl \$4,%esp # Remove argument call _set_process_mask\@4 -1: movl %fs:4,%edx - movl \$1,%eax # potential lock value - lock xchgl %eax,$tls::stacklock(%edx) # see if we can grab it - movl %eax,$tls::spinning(%edx) # flag if we are waiting for lock +1: movl \$1,%eax # potential lock value + lock xchgl %eax,$tls::stacklock(%ebx) # see if we can grab it + movl %eax,$tls::spinning(%ebx) # flag if we are waiting for lock testl %eax,%eax # it will be zero jz 2f # if so xorl %eax,%eax # nope. not zero call _low_priority_sleep # sleep jmp 1b # and loop -2: popl %ebx # saved errno - testl %ebx,%ebx # Is it < 0 +2: popl %edx # saved errno + testl %edx,%edx # Is it < 0 jl 3f # yup. ignore it - movl $tls::errno_addr(%edx),%eax - movl %ebx,(%eax) + movl $tls::errno_addr(%ebx),%eax + movl %edx,(%eax) 3: movl \$-4,%eax # now decrement aux stack - xadd %eax,$tls::stackptr(%edx) # and get pointer + xadd %eax,$tls::stackptr(%ebx) # and get pointer xorl %ebp,%ebp xchgl %ebp,-4(%eax) # get return address from signal stack xchgl %ebp,28(%esp) # store real return address - decl $tls::stacklock(%edx) # unlock + decl $tls::incyg(%ebx) + decl $tls::stacklock(%ebx) # unlock popl %eax popl %ebx @@ -186,6 +188,7 @@ _sigdelayed: pushl %ebx pushl %eax movl %fs:4,%ebx + incl $tls::incyg(%ebx) pushl $tls::saved_errno(%ebx) # saved errno 3: pushl $tls::oldmask(%ebx) # oldmask pushl $tls::sig(%ebx) # signal argument @@ -201,7 +204,8 @@ _sigdelayed: 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: ret +4: decl $tls::incyg(%ebx) + ret .global __ZN7_cygtls3popEv __ZN7_cygtls3popEv: @@ -243,6 +247,7 @@ __ZN7_cygtls6lockedEv: .extern __ZN7_cygtls19call_signal_handlerEv stabilize_sig_stack: 1: movl %fs:4,%edx + incl $tls::incyg(%edx) movl \$1,%eax lock xchgl %eax,$tls::stacklock(%edx) movl %eax,$tls::spinning(%edx) # flag if we are waiting for lock @@ -258,7 +263,8 @@ stabilize_sig_stack: addl %edx,%eax # of tls block call __ZN7_cygtls19call_signal_handlerEv jmp 1b -3: ret +3: decl $tls::incyg(%edx) + ret EOF } return $res; diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index f3f04decc..8f6b8c1ff 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -344,7 +344,6 @@ proc_subproc (DWORD what, DWORD val) pchildren[val]->pid, val, hchildren[val], pchildren[val]->hProcess); HANDLE h = hchildren[val]; hchildren[val] = pchildren[val]->hProcess; /* Filled out by child */ - sync_proc_subproc->release (); // Release the lock ASAP ForceCloseHandle1 (h, childhProc); ProtectHandle1 (pchildren[val]->hProcess, childhProc); rc = 0; diff --git a/winsup/cygwin/tlsoffsets.h b/winsup/cygwin/tlsoffsets.h index 96b06d7f2..3d07a17a6 100644 --- a/winsup/cygwin/tlsoffsets.h +++ b/winsup/cygwin/tlsoffsets.h @@ -41,12 +41,12 @@ //; $tls::pstackptr = 2704; //; $tls::sig = -1040; //; $tls::psig = 2708; -//; $tls::stacklock = -1036; -//; $tls::pstacklock = 2712; +//; $tls::incyg = -1036; +//; $tls::pincyg = 2712; //; $tls::spinning = -1032; //; $tls::pspinning = 2716; -//; $tls::incyg = -1028; -//; $tls::pincyg = 2720; +//; $tls::stacklock = -1028; +//; $tls::pstacklock = 2720; //; $tls::stack = -1024; //; $tls::pstack = 2724; //; $tls::padding = 0; @@ -93,12 +93,12 @@ #define tls_pstackptr (2704) #define tls_sig (-1040) #define tls_psig (2708) -#define tls_stacklock (-1036) -#define tls_pstacklock (2712) +#define tls_incyg (-1036) +#define tls_pincyg (2712) #define tls_spinning (-1032) #define tls_pspinning (2716) -#define tls_incyg (-1028) -#define tls_pincyg (2720) +#define tls_stacklock (-1028) +#define tls_pstacklock (2720) #define tls_stack (-1024) #define tls_pstack (2724) #define tls_padding (0)