* 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.
This commit is contained in:
Christopher Faylor 2004-02-13 19:34:32 +00:00
parent b3535c2730
commit edc4f86ad2
12 changed files with 135 additions and 101 deletions

View File

@ -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>

View File

@ -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 $@ $?

View File

@ -112,6 +112,7 @@ struct _cygtls
__stack_t *stackptr;
int sig;
unsigned stacklock;
unsigned spinning;
__stack_t stack[TLS_STACK_SIZE];
unsigned padding[0];

View File

@ -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;

View File

@ -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))

View File

@ -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

View File

@ -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);

View File

@ -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);
}

View File

@ -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
*/
/* 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

View File

@ -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:

View File

@ -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)

View File

@ -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;