Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2004-02-12 06:01:58 +0300
committerChristopher Faylor <me@cgf.cx>2004-02-12 06:01:58 +0300
commite431827c7cab81292e8cd4ec9d3a4a60b35a42f2 (patch)
tree1b9056071ae2ab09f0d3474904a4c5f71599128d /winsup/cygwin/exceptions.cc
parent2bc01fb1f5d3166c4960c5f9a1ff617f0f46a60d (diff)
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.
Diffstat (limited to 'winsup/cygwin/exceptions.cc')
-rw-r--r--winsup/cygwin/exceptions.cc106
1 files changed, 46 insertions, 60 deletions
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index 03df67f10..490756544 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -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");
}
-}