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 + + * 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 * 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 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 = <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 - */ - - -/* 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 +/* How long to wait for message/signals. Normally this is infinite. + 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;