Rename _threadinfo to _cygtls, throughout.

* cygtls.h (_cygtls::call_signal_handler): Rename from call_signal_handler_now.
(_cygtls::push): Make second argument mandatory.
(_cygtls::fixup_after_fork): Declare new function.
(_cygtls::lock): Ditto.
* cygtls.cc (_cygtls::fixup_after_fork): Define new function.
* dcrt0.cc (cygwin_finished_initializing): Define as bool.
(alloc_stack): Use _tlstop rather than arbitrary variable in probably vain
attempt to avoid strange fork problem on CTRL-C.
(dll_crt0_0): Remove obsolete winpids::init call.
* dll_init.cc (dll_dllcrt0): Detect forkee condition as equivalent to
initializing.
* winsup.h (cygwin_finished_initializing): Declare as bool.
* exceptions.cc (handle_exceptions): Rely on cygwin_finished_initializing to
determine how to handle exception during process startup.
(_cygtls::call_signal_handler): Rename from call_signal_handler_now.
(_cygtls::interrupt_now): Fill in second argument to push.
(signal_fixup_after_fork): Eliminate.
(setup_handler): Initialize locked to avoid potential inappropriate unlock.
Resume thread if it has acquired the stack lock.
(ctrl_c_handler): Just exit if ctrl-c is hit before cygiwn has finished
initializing.
* fork.cc (sync_with_child): Don't call abort since it can cause exit
deadlocks.
(sync_with_child): Change debugging output slightly.
(fork_child): Set cygwin_finished_initializing here.  Call _cygtls fork fixup
and explicitly call sigproc_init.
(fork_parent): Release malloc lock on fork failure.
(vfork): Call signal handler via _my_tls.
* sigproc.cc (sig_send): Ditto.
* syscalls.cc (readv): Ditto.
* termios.cc (tcsetattr): Ditto.
* wait.cc (wait4): Ditto.
* signal.cc (nanosleep): Ditto.
(abort): Ditto.
(kill_pgrp): Avoid killing self if exiting.
* sync.cc (muto::acquire): Remove (temporarily?) ill-advised exiting_thread
check.
* gendef (_sigfe): Be more agressive in protecting stack pointer from other
access by signal thread.
(_cygtls::locked): Define new function.
(_sigbe): Ditto.
(_cygtls::pop): Protect edx.
(_cygtls::lock): Use guaranteed method to set eax to 1.
(longjmp): Aggressively protect signal stack.
* miscfuncs.cc (low_priority_sleep): Reduce "sleep time" for secs == 0.
* pinfo.cc (winpids::set): Counterintuitively use malloc's lock to protect
simultaneous access to the pids list since there are pathological conditions
which can cause malloc to call winpid.
(winpids::init): Eliminate.
* pinfo.h (winpids::cs): Eliminate declaration.
* pinfo.h (winpids::init): Eliminate definition.
This commit is contained in:
Christopher Faylor
2004-02-12 03:01:58 +00:00
parent 2bc01fb1f5
commit e431827c7c
23 changed files with 287 additions and 209 deletions

View File

@ -519,7 +519,7 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *)
break;
}
if (!myself->progname[0]
if (!cygwin_finished_initializing
|| GetCurrentThreadId () == sigtid
|| (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_DFL
|| (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_IGN
@ -692,10 +692,10 @@ interruptible (DWORD pc)
return res;
}
void __stdcall
_threadinfo::interrupt_setup (int sig, void *handler,
_cygtls::interrupt_setup (int sig, void *handler,
struct sigaction& siga)
{
push ((__stack_t) sigdelayed);
push ((__stack_t) sigdelayed, false);
oldmask = myself->getsigmask ();
newmask = oldmask | siga.sa_mask | SIGTOMASK (sig);
sa_flags = siga.sa_flags;
@ -717,28 +717,16 @@ _threadinfo::interrupt_setup (int sig, void *handler,
}
bool
_threadinfo::interrupt_now (CONTEXT *ctx, int sig, void *handler,
_cygtls::interrupt_now (CONTEXT *ctx, int sig, void *handler,
struct sigaction& siga)
{
push ((__stack_t) ctx->Eip);
push ((__stack_t) ctx->Eip, false);
interrupt_setup (sig, handler, siga);
ctx->Eip = pop ();
SetThreadContext (*this, ctx); /* Restart the thread in a new location */
return 1;
}
void __stdcall
signal_fixup_after_fork ()
{
if (_my_tls.sig)
{
_my_tls.sig = 0;
_my_tls.stackptr = _my_tls.stack + 1; // FIXME?
set_signal_mask (_my_tls.oldmask);
}
sigproc_init ();
}
extern "C" void __stdcall
set_sig_errno (int e)
{
@ -747,13 +735,14 @@ set_sig_errno (int e)
// sigproc_printf ("errno %d", e);
}
static int setup_handler (int, void *, struct sigaction&, _threadinfo *tls)
static int setup_handler (int, void *, struct sigaction&, _cygtls *tls)
__attribute__((regparm(3)));
static int
setup_handler (int sig, void *handler, struct sigaction& siga, _threadinfo *tls)
setup_handler (int sig, void *handler, struct sigaction& siga, _cygtls *tls)
{
CONTEXT cx;
bool interrupted = false;
bool locked = false;
if (tls->sig)
{
@ -762,12 +751,11 @@ setup_handler (int sig, void *handler, struct sigaction& siga, _threadinfo *tls)
goto out;
}
int locked;
for (int i = 0; i < CALL_HANDLER_RETRY; i++)
{
locked = tls->lock ();
__stack_t *retaddr_on_stack = tls->stackptr - 1;
if (retaddr_on_stack >= tls->stack)
tls->lock ();
locked = true;
if (tls->stackptr > tls->stack)
{
tls->reset_exception ();
tls->interrupt_setup (sig, handler, siga);
@ -776,14 +764,14 @@ setup_handler (int sig, void *handler, struct sigaction& siga, _threadinfo *tls)
break;
}
tls->unlock ();
locked = false;
DWORD res;
HANDLE hth = (HANDLE) *tls;
/* Suspend the thread which will receive the signal. But first ensure that
this thread doesn't have any mutos. (FIXME: Someday we should just grab
all of the mutos rather than checking for them)
For Windows 95, we also have to ensure that the addresses returned by GetThreadContext
are valid.
/* Suspend the thread which will receive the signal.
For Windows 95, we also have to ensure that the addresses returned by
GetThreadContext are valid.
If one of these conditions is not true we loop for a fixed number of times
since we don't want to stall the signal handler. FIXME: Will this result in
noticeable delays?
@ -799,31 +787,25 @@ setup_handler (int sig, void *handler, struct sigaction& siga, _threadinfo *tls)
sigproc_printf ("suspending mainthread PC %p", cx.Eip);
#endif
res = SuspendThread (hth);
/* Just release the lock now since we hav suspended the main thread and it
definitely can't be grabbing it now. This will have to change, of course,
if/when we can send signals to other than the main thread. */
/* Just set pending if thread is already suspended */
if (res)
{
(void) ResumeThread (hth);
break;
}
// FIXME - add check for reentering of DLL here
cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
if (!GetThreadContext (hth, &cx))
system_printf ("couldn't get context of main thread, %E");
else if (interruptible (cx.Eip))
interrupted = tls->interrupt_now (&cx, sig, handler, siga);
if (!tls->locked ())
{
cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
if (!GetThreadContext (hth, &cx))
system_printf ("couldn't get context of main thread, %E");
else if (interruptible (cx.Eip))
interrupted = tls->interrupt_now (&cx, sig, handler, siga);
}
res = ResumeThread (hth);
if (interrupted)
break;
tls->unlock ();
locked = false;
sigproc_printf ("couldn't interrupt. trying again.");
low_priority_sleep (0);
}
@ -845,6 +827,10 @@ static BOOL WINAPI
ctrl_c_handler (DWORD type)
{
static bool saw_close;
if (!cygwin_finished_initializing)
ExitProcess (STATUS_CONTROL_C_EXIT);
_my_tls.remove (INFINITE);
/* Return FALSE to prevent an "End task" dialog box from appearing
@ -977,7 +963,7 @@ sigpacket::process ()
/* nothing to do */;
else if (tls && sigismember (&tls->sigwait_mask, si.si_signo))
insigwait_mask = true;
else if (!tls && (tls = _threadinfo::find_tls (si.si_signo)))
else if (!tls && (tls = _cygtls::find_tls (si.si_signo)))
insigwait_mask = true;
else if (!(masked = sigismember (mask, si.si_signo)) && tls)
masked = sigismember (&tls->sigmask, si.si_signo);
@ -1153,36 +1139,36 @@ events_terminate (void)
exit_already = 1;
}
extern "C" {
int __stdcall
call_signal_handler_now ()
int
_cygtls::call_signal_handler ()
{
int sa_flags = 0;
while (_my_tls.sig && _my_tls.stackptr > _my_tls.stack)
int this_sa_flags = 0;
/* Call signal handler. No need to set stacklock since sig effectively
implies that. */
while (sig)
{
sa_flags = _my_tls.sa_flags;
int sig = _my_tls.sig;
void (*sigfunc) (int) = _my_tls.func;
this_sa_flags = sa_flags;
int thissig = sig;
void (*sigfunc) (int) = func;
(void) _my_tls.pop ();
(void) pop ();
reset_signal_arrived ();
sigset_t oldmask = _my_tls.oldmask;
int this_errno = _my_tls.saved_errno;
set_process_mask (_my_tls.newmask);
_my_tls.sig = 0;
sigfunc (sig);
sigset_t oldmask = oldmask;
int this_errno = saved_errno;
set_process_mask (newmask);
sig = 0;
sigfunc (thissig);
set_process_mask (oldmask);
if (this_errno >= 0)
set_errno (this_errno);
}
return sa_flags & SA_RESTART;
return this_sa_flags & SA_RESTART;
}
void __stdcall
extern "C" void __stdcall
reset_signal_arrived ()
{
(void) ResetEvent (signal_arrived);
sigproc_printf ("reset signal_arrived");
}
}