diff options
author | Christopher Faylor <me@cgf.cx> | 2004-02-13 19:34:32 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2004-02-13 19:34:32 +0000 |
commit | edc4f86ad282702ab7c029cf65b87ec616bda05e (patch) | |
tree | 2abde4171eaab1863d78128ba2ef6418485eff57 | |
parent | b3535c273043da91247840c4af64bb573d5517c4 (diff) | |
download | cygnal-edc4f86ad282702ab7c029cf65b87ec616bda05e.tar.gz cygnal-edc4f86ad282702ab7c029cf65b87ec616bda05e.tar.bz2 cygnal-edc4f86ad282702ab7c029cf65b87ec616bda05e.zip |
* Makefile.in (clean): Remove sigfe.s.
(sigfe.s): Ensure that sigfe.s will be regenerated if it does not exist.
* dll_init.cc (dll_dllcrt0): Simplify initializing tests.
* exceptions.cc (setup_handler): Detect when stub caller is either spinning or
has acquired the lock after being suspended to avoid windows problems with
suspending a win32 API call.
* cygtls.h (_cygtls::spinning): Declare new element.
* gendef: Remove unused _siglist_index and _siglist declaration.
(_sigfe): Set spinning element when potentially looping, waiting for lock.
(_sigbe): Ditto.
(_cygtls::lock): Ditto.
(_longjmp): Ditto.
* tlsoffsets.h: Regenerate.
* pinfo.cc (_pinfo::exit): Set final exit state here. Call sigproc_terminate
if invoked with 'norecord'. Clear any residual _cygtls stuff.
* winsup.h (exit_states): Define ES_FINAL.
* spawn.cc (spawn_guts): Don't call proc_terminate specifically when execing.
Let _pinfo::exit handle that case.
* sigproc.cc (wait_subproc): Always exit loop early when proc_loop_wait.
* init.cc (munge_threadfunc): Eliminate unused argument.
(dll_entry): Reflect above change in call to munge_threadfunc.
-rw-r--r-- | winsup/cygwin/ChangeLog | 30 | ||||
-rw-r--r-- | winsup/cygwin/Makefile.in | 7 | ||||
-rw-r--r-- | winsup/cygwin/cygtls.h | 1 | ||||
-rw-r--r-- | winsup/cygwin/dll_init.cc | 9 | ||||
-rw-r--r-- | winsup/cygwin/exceptions.cc | 4 | ||||
-rwxr-xr-x | winsup/cygwin/gendef | 5 | ||||
-rw-r--r-- | winsup/cygwin/init.cc | 6 | ||||
-rw-r--r-- | winsup/cygwin/pinfo.cc | 8 | ||||
-rw-r--r-- | winsup/cygwin/sigproc.cc | 62 | ||||
-rw-r--r-- | winsup/cygwin/spawn.cc | 3 | ||||
-rw-r--r-- | winsup/cygwin/tlsoffsets.h | 96 | ||||
-rw-r--r-- | winsup/cygwin/winsup.h | 3 |
12 files changed, 134 insertions, 100 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index ef35a3976..20c8c3ebb 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,31 @@ +2004-02-13 Christopher Faylor <cgf@redhat.com> + + * Makefile.in (clean): Remove sigfe.s. + (sigfe.s): Ensure that sigfe.s will be regenerated if it does not exist. + * dll_init.cc (dll_dllcrt0): Simplify initializing tests. + + * exceptions.cc (setup_handler): Detect when stub caller is either + spinning or has acquired the lock after being suspended to avoid + windows problems with suspending a win32 API call. + + * cygtls.h (_cygtls::spinning): Declare new element. + * gendef: Remove unused _siglist_index and _siglist declaration. + (_sigfe): Set spinning element when potentially looping, waiting for lock. + (_sigbe): Ditto. + (_cygtls::lock): Ditto. + (_longjmp): Ditto. + * tlsoffsets.h: Regenerate. + * pinfo.cc (_pinfo::exit): Set final exit state here. Call sigproc_terminate if + invoked with 'norecord'. Clear any residual _cygtls stuff. + * winsup.h (exit_states): Define ES_FINAL. + * spawn.cc (spawn_guts): Don't call proc_terminate specifically when + execing. Let _pinfo::exit handle that case. + + * sigproc.cc (wait_subproc): Always exit loop early when proc_loop_wait. + + * init.cc (munge_threadfunc): Eliminate unused argument. + (dll_entry): Reflect above change in call to munge_threadfunc. + 2004-02-11 Christopher Faylor <cgf@redhat.com> * gendef (_sigbe): Zero location on pop. @@ -88,7 +116,7 @@ (_sigbe): Ditto. (_threadinfo::lock): Ditto. (_threadinfo::pop): Eliminate left-over stack unlock. - * sigproc.cc (proc_subproc): Chnage debugging output to printed + * sigproc.cc (proc_subproc): Change debugging output to printed warning. 2004-02-08 Christopher Faylor <cgf@redhat.com> diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index 54ae6e991..887ab1e44 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -224,6 +224,7 @@ cygthread_CFLAGS:=-fomit-frame-pointer cygtls_CFLAGS:=-fomit-frame-pointer devices_CFLAGS:=-fomit-frame-pointer -Os dir_CFLAGS:=-fomit-frame-pointer +dll_init_CFLAGS:=-fomit-frame-pointer fcntl_CFLAGS:=-fomit-frame-pointer fhandler_CFLAGS:=-fomit-frame-pointer fhandler_clipboard_CFLAGS:=-fomit-frame-pointer @@ -346,7 +347,7 @@ uninstall-man: done clean: - -rm -f *.o *.dll *.a *.exp junk *.base version.cc regexp/*.o winver_stamp *.exe *.d *stamp* *_magic.h + -rm -f *.o *.dll *.a *.exp junk *.base version.cc regexp/*.o winver_stamp *.exe *.d *stamp* *_magic.h sigfe.s maintainer-clean realclean: clean @echo "This command is intended for maintainers to use;" @@ -437,7 +438,9 @@ $(srcdir)/tlsoffsets.h: gentls_offsets cygtls.h $^ $@ $(COMPILE_CXX) sigfe.s: $(DEF_FILE) - @touch $@ + @[ -s $@ ] || \ + { rm -f $(DEF_FILE); $(MAKE) -s -j1 $(DEF_FILE); }; \ + [ -s $@ ] && touch $@ sigfe.o: sigfe.s $(CC) -c -o $@ $? diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h index 78f61242b..444da265c 100644 --- a/winsup/cygwin/cygtls.h +++ b/winsup/cygwin/cygtls.h @@ -112,6 +112,7 @@ struct _cygtls __stack_t *stackptr; int sig; unsigned stacklock; + unsigned spinning; __stack_t stack[TLS_STACK_SIZE]; unsigned padding[0]; diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc index a1901a02d..a3817d76e 100644 --- a/winsup/cygwin/dll_init.cc +++ b/winsup/cygwin/dll_init.cc @@ -23,7 +23,7 @@ extern void __stdcall check_sanity_and_sync (per_process *); dll_list NO_COPY dlls; -static NO_COPY int in_forkee = 0; +static int NO_COPY in_forkee; static int dll_global_dtors_recorded; /* Run destructors for all DLLs on exit. */ @@ -183,7 +183,7 @@ dll_list::alloc (HINSTANCE h, per_process *p, dll_type type) void dll_list::detach (void *retaddr) { - if (!myself || myself->process_state == PID_EXITED) + if (!myself || exit_state) return; MEMORY_BASIC_INFORMATION m; if (!VirtualQuery (retaddr, &m, sizeof m)) @@ -358,6 +358,7 @@ dll_dllcrt0 (HMODULE h, per_process *p) p = &__cygwin_user_data; else *(p->impure_ptr_ptr) = __cygwin_user_data.impure_ptr; + bool initializing = in_forkee || cygwin_finished_initializing; /* Partially initialize Cygwin guts for non-cygwin apps. */ if (dynamically_loaded && user_data->magic_biscuit == 0) @@ -371,7 +372,7 @@ dll_dllcrt0 (HMODULE h, per_process *p) initializing, then the DLL must be a cygwin-aware DLL that was explicitly linked into the program rather than a dlopened DLL. */ - if (!in_forkee && !cygwin_finished_initializing) + if (!initializing) type = DLL_LINK; else { @@ -387,7 +388,7 @@ dll_dllcrt0 (HMODULE h, per_process *p) initialize the DLL. If we haven't finished initializing, it may not be safe to call the dll's "main" since not all of cygwin's internal structures may have been set up. */ - if (!d || ((in_forkee || cygwin_finished_initializing) && !d->init ())) + if (!d || (initializing && !d->init ())) return -1; return (DWORD) d; diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 490756544..118223e03 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -788,12 +788,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) + if (res || tls->stackptr > tls->stack) { (void) ResumeThread (hth); break; } - if (!tls->locked ()) + if (!tls->locked () && !tls->spinning) { cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; if (!GetThreadContext (hth, &cx)) diff --git a/winsup/cygwin/gendef b/winsup/cygwin/gendef index 4395ac6de..22acf87df 100755 --- a/winsup/cygwin/gendef +++ b/winsup/cygwin/gendef @@ -76,8 +76,6 @@ sub fefunc { my $fe = '_' . shift; my $extra; my $res = <<EOF; - .extern _siglist_index - .extern _siglist .extern $func .global $fe $fe: @@ -96,6 +94,7 @@ __sigfe: 1: movl %fs:4,%edx # location of bottom of stack 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 orl %eax,%eax # it will be zero jz 2f # if so xorl %eax,%eax # nope. It was not zero @@ -120,6 +119,7 @@ __sigbe: 1: movl %fs:4,%edx # address of bottom of tls 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 orl %eax,%eax # it will be zero jz 2f # if so xorl %eax,%eax # nope. not zero @@ -242,6 +242,7 @@ _longjmp: 1: movl %fs:4,%edx movl \$1,%eax lock xchgl %eax,$tls::stacklock(%edx) + movl %eax,$tls::spinning(%edx) # flag if we are waiting for lock orl %eax,%eax jz 2f xorl %eax,%eax diff --git a/winsup/cygwin/init.cc b/winsup/cygwin/init.cc index 8bbc89bfb..b6d187328 100644 --- a/winsup/cygwin/init.cc +++ b/winsup/cygwin/init.cc @@ -56,7 +56,7 @@ prime_threads () /* If possible, redirect the thread entry point to a cygwin routine which adds tls stuff to the stack. */ static void -munge_threadfunc (HANDLE cygwin_hmodule) +munge_threadfunc () { char **ebp = (char **) __builtin_frame_address (0); if (!threadfunc_ix) @@ -67,7 +67,7 @@ munge_threadfunc (HANDLE cygwin_hmodule) threadfunc_ix = peb - ebp; goto foundit; } -#ifdef DEBUGGING +#ifdef DEBUGGING_HARD system_printf ("non-fatal warning: unknown thread! search_for %p, cygthread::stub %p, calibration_thread %p, possible func offset %p", search_for, cygthread::stub, calibration_thread, ebp[137]); #endif @@ -102,7 +102,7 @@ dll_entry (HANDLE h, DWORD reason, void *static_load) case DLL_PROCESS_DETACH: break; case DLL_THREAD_ATTACH: - munge_threadfunc (h); + munge_threadfunc (); break; case DLL_THREAD_DETACH: _my_tls.remove (0); diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index a9a0b80e7..0dd465ae4 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -31,6 +31,7 @@ details. */ #include "cygheap.h" #include "fhandler.h" #include "cygmalloc.h" +#include "cygtls.h" static char NO_COPY pinfo_dummy[sizeof (_pinfo)] = {0}; @@ -104,6 +105,10 @@ pinfo_init (char **envp, int envc) void _pinfo::exit (UINT n, bool norecord) { + exit_state = ES_FINAL; + cygthread::terminate (); + if (norecord) + sigproc_terminate (); if (this) { if (!norecord) @@ -116,8 +121,9 @@ _pinfo::exit (UINT n, bool norecord) add_rusage (&rusage_self, &r); } - cygthread::terminate (); sigproc_printf ("Calling ExitProcess %d", n); + _my_tls.stacklock = 0; + _my_tls.stackptr = _my_tls.stack; ExitProcess (n); } diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index c013e0d20..5d7e049be 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -70,26 +70,6 @@ static pending_signals sigqueue; struct sigaction *global_sigs; -void __stdcall -sigalloc () -{ - cygheap->sigs = global_sigs = - (struct sigaction *) ccalloc (HEAP_SIGS, NSIG, sizeof (struct sigaction)); -} - -void __stdcall -signal_fixup_after_exec () -{ - global_sigs = cygheap->sigs; - /* Set up child's signal handlers */ - for (int i = 0; i < NSIG; i++) - { - global_sigs[i].sa_mask = 0; - if (global_sigs[i].sa_handler != SIG_IGN) - global_sigs[i].sa_handler = SIG_DFL; - } -} - /* * Global variables */ @@ -101,19 +81,15 @@ char NO_COPY myself_nowait_dummy[1] = {'0'};// Flag to sig_send that signal goes HANDLE NO_COPY signal_arrived; // Event signaled when a signal has // resulted in a user-specified // function call -/* - * Common variables - */ +#define Static static NO_COPY /* How long to wait for message/signals. Normally this is infinite. - * On termination, however, these are set to zero as a flag to exit. - */ - -#define Static static NO_COPY + On termination, however, these are set to zero as a flag to exit. */ Static DWORD proc_loop_wait = 1000; // Wait for subprocesses to exit +Static HANDLE sendsig_tome; HANDLE NO_COPY sigCONT; // Used to "STOP" a process Static cygthread *hwait_sig; // Handle of wait_sig thread Static cygthread *hwait_subproc; // Handle of sig_subproc thread @@ -149,6 +125,26 @@ static DWORD WINAPI wait_sig (VOID *arg); static int __stdcall stopped_or_terminated (waitq *, _pinfo *); static DWORD WINAPI wait_subproc (VOID *); +void __stdcall +sigalloc () +{ + cygheap->sigs = global_sigs = + (struct sigaction *) ccalloc (HEAP_SIGS, NSIG, sizeof (struct sigaction)); +} + +void __stdcall +signal_fixup_after_exec () +{ + global_sigs = cygheap->sigs; + /* Set up child's signal handlers */ + for (int i = 0; i < NSIG; i++) + { + global_sigs[i].sa_mask = 0; + if (global_sigs[i].sa_handler != SIG_IGN) + global_sigs[i].sa_handler = SIG_DFL; + } +} + /* Determine if the parent process is alive. */ @@ -1215,17 +1211,13 @@ wait_subproc (VOID *) { DWORD rc = WaitForMultipleObjects (nchildren + 1, events, FALSE, proc_loop_wait); + if (!proc_loop_wait) + break; if (rc == WAIT_TIMEOUT) - if (!proc_loop_wait) - break; // Exiting - else - continue; + continue; if (rc == WAIT_FAILED) { - if (!proc_loop_wait) - break; - /* It's ok to get an ERROR_INVALID_HANDLE since another thread may have closed a handle in the children[] array. So, we try looping a couple of times to stabilize. FIXME - this is not foolproof. Probably, this @@ -1274,8 +1266,6 @@ wait_subproc (VOID *) si.si_stime = 0; #endif rc = proc_subproc (PROC_CHILDTERMINATED, rc); - if (!proc_loop_wait) // Don't bother if wait_subproc is - break; // exiting /* Send a SIGCHLD to myself. We do this here, rather than in proc_subproc to avoid the proc_subproc lock since the signal thread will eventually diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 7f6231e14..992bad1ab 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -745,7 +745,7 @@ spawn_guts (const char * prog_arg, const char *const *argv, (void) sigprocmask (SIG_BLOCK, &child_block, &cleanup.oldmask); } - /* Fixup the parent datastructure if needed and resume the child's + /* Fixup the parent data structures if needed and resume the child's main thread. */ if (!cygheap->fdtab.need_fixup_before ()) cygheap_setup_for_child_cleanup (newheap, &ciresrv, 0); @@ -908,7 +908,6 @@ spawn_guts (const char * prog_arg, const char *const *argv, { case _P_OVERLAY: ForceCloseHandle1 (pi.hProcess, childhProc); - proc_terminate (); myself->exit (res, 1); break; case _P_WAIT: diff --git a/winsup/cygwin/tlsoffsets.h b/winsup/cygwin/tlsoffsets.h index e1da0395a..af55081dc 100644 --- a/winsup/cygwin/tlsoffsets.h +++ b/winsup/cygwin/tlsoffsets.h @@ -1,96 +1,100 @@ //;# autogenerated: Do not edit. -//; $tls::func = -3740; +//; $tls::func = -3744; //; $tls::pfunc = 0; -//; $tls::saved_errno = -3736; +//; $tls::saved_errno = -3740; //; $tls::psaved_errno = 4; -//; $tls::sa_flags = -3732; +//; $tls::sa_flags = -3736; //; $tls::psa_flags = 8; -//; $tls::oldmask = -3728; +//; $tls::oldmask = -3732; //; $tls::poldmask = 12; -//; $tls::newmask = -3724; +//; $tls::newmask = -3728; //; $tls::pnewmask = 16; -//; $tls::event = -3720; +//; $tls::event = -3724; //; $tls::pevent = 20; -//; $tls::errno_addr = -3716; +//; $tls::errno_addr = -3720; //; $tls::perrno_addr = 24; -//; $tls::initialized = -3712; +//; $tls::initialized = -3716; //; $tls::pinitialized = 28; -//; $tls::sigmask = -3708; +//; $tls::sigmask = -3712; //; $tls::psigmask = 32; -//; $tls::sigwait_mask = -3704; +//; $tls::sigwait_mask = -3708; //; $tls::psigwait_mask = 36; -//; $tls::sigwait_info = -3700; +//; $tls::sigwait_info = -3704; //; $tls::psigwait_info = 40; -//; $tls::threadkill = -3696; +//; $tls::threadkill = -3700; //; $tls::pthreadkill = 44; -//; $tls::infodata = -3692; +//; $tls::infodata = -3696; //; $tls::pinfodata = 48; -//; $tls::tid = -3544; +//; $tls::tid = -3548; //; $tls::ptid = 196; -//; $tls::local_clib = -3540; +//; $tls::local_clib = -3544; //; $tls::plocal_clib = 200; -//; $tls::locals = -2612; +//; $tls::locals = -2616; //; $tls::plocals = 1128; -//; $tls::prev = -1044; +//; $tls::prev = -1048; //; $tls::pprev = 2696; -//; $tls::next = -1040; +//; $tls::next = -1044; //; $tls::pnext = 2700; -//; $tls::stackptr = -1036; +//; $tls::stackptr = -1040; //; $tls::pstackptr = 2704; -//; $tls::sig = -1032; +//; $tls::sig = -1036; //; $tls::psig = 2708; -//; $tls::stacklock = -1028; +//; $tls::stacklock = -1032; //; $tls::pstacklock = 2712; +//; $tls::spinning = -1028; +//; $tls::pspinning = 2716; //; $tls::stack = -1024; -//; $tls::pstack = 2716; +//; $tls::pstack = 2720; //; $tls::padding = 0; -//; $tls::ppadding = 3740; +//; $tls::ppadding = 3744; //; __DATA__ -#define tls_func (-3740) +#define tls_func (-3744) #define tls_pfunc (0) -#define tls_saved_errno (-3736) +#define tls_saved_errno (-3740) #define tls_psaved_errno (4) -#define tls_sa_flags (-3732) +#define tls_sa_flags (-3736) #define tls_psa_flags (8) -#define tls_oldmask (-3728) +#define tls_oldmask (-3732) #define tls_poldmask (12) -#define tls_newmask (-3724) +#define tls_newmask (-3728) #define tls_pnewmask (16) -#define tls_event (-3720) +#define tls_event (-3724) #define tls_pevent (20) -#define tls_errno_addr (-3716) +#define tls_errno_addr (-3720) #define tls_perrno_addr (24) -#define tls_initialized (-3712) +#define tls_initialized (-3716) #define tls_pinitialized (28) -#define tls_sigmask (-3708) +#define tls_sigmask (-3712) #define tls_psigmask (32) -#define tls_sigwait_mask (-3704) +#define tls_sigwait_mask (-3708) #define tls_psigwait_mask (36) -#define tls_sigwait_info (-3700) +#define tls_sigwait_info (-3704) #define tls_psigwait_info (40) -#define tls_threadkill (-3696) +#define tls_threadkill (-3700) #define tls_pthreadkill (44) -#define tls_infodata (-3692) +#define tls_infodata (-3696) #define tls_pinfodata (48) -#define tls_tid (-3544) +#define tls_tid (-3548) #define tls_ptid (196) -#define tls_local_clib (-3540) +#define tls_local_clib (-3544) #define tls_plocal_clib (200) -#define tls_locals (-2612) +#define tls_locals (-2616) #define tls_plocals (1128) -#define tls_prev (-1044) +#define tls_prev (-1048) #define tls_pprev (2696) -#define tls_next (-1040) +#define tls_next (-1044) #define tls_pnext (2700) -#define tls_stackptr (-1036) +#define tls_stackptr (-1040) #define tls_pstackptr (2704) -#define tls_sig (-1032) +#define tls_sig (-1036) #define tls_psig (2708) -#define tls_stacklock (-1028) +#define tls_stacklock (-1032) #define tls_pstacklock (2712) +#define tls_spinning (-1028) +#define tls_pspinning (2716) #define tls_stack (-1024) -#define tls_pstack (2716) +#define tls_pstack (2720) #define tls_padding (0) -#define tls_ppadding (3740) +#define tls_ppadding (3744) diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h index d8930f9c6..93cdceed2 100644 --- a/winsup/cygwin/winsup.h +++ b/winsup/cygwin/winsup.h @@ -197,7 +197,8 @@ enum exit_states ES_TITLE, ES_HUP_PGRP, ES_HUP_SID, - ES_TTY_TERMINATE + ES_TTY_TERMINATE, + ES_FINAL }; extern exit_states exit_state; |