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:
parent
2bc01fb1f5
commit
e431827c7c
|
@ -1,3 +1,60 @@
|
|||
2004-02-11 Christopher Faylor <cgf@redhat.com>
|
||||
|
||||
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.
|
||||
|
||||
2004-02-11 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* security.cc (get_nt_object_attribute): Fix error handling.
|
||||
|
|
|
@ -266,7 +266,7 @@ struct init_cygheap
|
|||
#ifdef NEWVFORK
|
||||
fhandler_tty_slave *ctty_on_hold;
|
||||
#endif
|
||||
struct _threadinfo **threadlist;
|
||||
struct _cygtls **threadlist;
|
||||
size_t sthreads;
|
||||
int open_fhs;
|
||||
void close_ctty ();
|
||||
|
|
|
@ -20,6 +20,7 @@ details. */
|
|||
#include "dtable.h"
|
||||
#include "cygheap.h"
|
||||
#include "cygthread.h"
|
||||
#include "pinfo.h"
|
||||
#include "sigproc.h"
|
||||
|
||||
class sentry
|
||||
|
@ -32,7 +33,7 @@ public:
|
|||
sentry () {destroy = 0;}
|
||||
sentry (DWORD wait) {destroy = lock->acquire (wait);}
|
||||
~sentry () {if (destroy) lock->release ();}
|
||||
friend void _threadinfo::init ();
|
||||
friend void _cygtls::init ();
|
||||
};
|
||||
|
||||
muto NO_COPY *sentry::lock;
|
||||
|
@ -42,27 +43,27 @@ static size_t NO_COPY nthreads;
|
|||
#define THREADLIST_CHUNK 256
|
||||
|
||||
void
|
||||
_threadinfo::init ()
|
||||
_cygtls::init ()
|
||||
{
|
||||
if (cygheap->threadlist)
|
||||
memset (cygheap->threadlist, 0, cygheap->sthreads * sizeof (cygheap->threadlist[0]));
|
||||
else
|
||||
{
|
||||
cygheap->sthreads = THREADLIST_CHUNK;
|
||||
cygheap->threadlist = (_threadinfo **) ccalloc (HEAP_TLS, cygheap->sthreads,
|
||||
cygheap->threadlist = (_cygtls **) ccalloc (HEAP_TLS, cygheap->sthreads,
|
||||
sizeof (cygheap->threadlist[0]));
|
||||
}
|
||||
new_muto1 (sentry::lock, sentry_lock);
|
||||
}
|
||||
|
||||
void
|
||||
_threadinfo::set_state (bool is_exception)
|
||||
_cygtls::set_state (bool is_exception)
|
||||
{
|
||||
initialized = CYGTLS_INITIALIZED + is_exception;
|
||||
}
|
||||
|
||||
void
|
||||
_threadinfo::reset_exception ()
|
||||
_cygtls::reset_exception ()
|
||||
{
|
||||
if (initialized == CYGTLS_EXCEPTION)
|
||||
{
|
||||
|
@ -75,14 +76,14 @@ _threadinfo::reset_exception ()
|
|||
|
||||
/* Two calls to get the stack right... */
|
||||
void
|
||||
_threadinfo::call (DWORD (*func) (void *, void *), void *arg)
|
||||
_cygtls::call (DWORD (*func) (void *, void *), void *arg)
|
||||
{
|
||||
char buf[CYGTLS_PADSIZE];
|
||||
call2 (func, arg, buf);
|
||||
}
|
||||
|
||||
void
|
||||
_threadinfo::call2 (DWORD (*func) (void *, void *), void *arg, void *buf)
|
||||
_cygtls::call2 (DWORD (*func) (void *, void *), void *arg, void *buf)
|
||||
{
|
||||
exception_list except_entry;
|
||||
/* Initialize this thread's ability to respond to things like
|
||||
|
@ -95,7 +96,7 @@ _threadinfo::call2 (DWORD (*func) (void *, void *), void *arg, void *buf)
|
|||
}
|
||||
|
||||
void
|
||||
_threadinfo::init_thread (void *x, DWORD (*func) (void *, void *))
|
||||
_cygtls::init_thread (void *x, DWORD (*func) (void *, void *))
|
||||
{
|
||||
if (x)
|
||||
{
|
||||
|
@ -125,7 +126,7 @@ _threadinfo::init_thread (void *x, DWORD (*func) (void *, void *))
|
|||
sentry here (INFINITE);
|
||||
if (nthreads >= cygheap->sthreads)
|
||||
{
|
||||
cygheap->threadlist = (_threadinfo **)
|
||||
cygheap->threadlist = (_cygtls **)
|
||||
crealloc (cygheap->threadlist, (cygheap->sthreads += THREADLIST_CHUNK)
|
||||
* sizeof (cygheap->threadlist[0]));
|
||||
memset (cygheap->threadlist + nthreads, 0, THREADLIST_CHUNK * sizeof (cygheap->threadlist[0]));
|
||||
|
@ -135,7 +136,22 @@ _threadinfo::init_thread (void *x, DWORD (*func) (void *, void *))
|
|||
}
|
||||
|
||||
void
|
||||
_threadinfo::remove (DWORD wait)
|
||||
_cygtls::fixup_after_fork ()
|
||||
{
|
||||
if (sig)
|
||||
{
|
||||
set_signal_mask (oldmask);
|
||||
sig = 0;
|
||||
}
|
||||
stacklock = 0;
|
||||
stackptr = stack + 1; // FIXME?
|
||||
#ifdef DEBUGGING
|
||||
memset (stackptr, 0, sizeof (stack) - sizeof (stack[0]));
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
_cygtls::remove (DWORD wait)
|
||||
{
|
||||
debug_printf ("wait %p\n", wait);
|
||||
sentry here (wait);
|
||||
|
@ -153,7 +169,7 @@ _threadinfo::remove (DWORD wait)
|
|||
}
|
||||
|
||||
void
|
||||
_threadinfo::push (__stack_t addr, bool exception)
|
||||
_cygtls::push (__stack_t addr, bool exception)
|
||||
{
|
||||
if (exception)
|
||||
lock ();
|
||||
|
@ -166,13 +182,13 @@ _threadinfo::push (__stack_t addr, bool exception)
|
|||
#define BAD_IX ((size_t) -1)
|
||||
static size_t NO_COPY threadlist_ix = BAD_IX;
|
||||
|
||||
_threadinfo *
|
||||
_threadinfo::find_tls (int sig)
|
||||
_cygtls *
|
||||
_cygtls::find_tls (int sig)
|
||||
{
|
||||
debug_printf ("sig %d\n", sig);
|
||||
sentry here (INFINITE);
|
||||
__asm__ volatile (".equ _threadlist_exception_return,.");
|
||||
_threadinfo *res = NULL;
|
||||
_cygtls *res = NULL;
|
||||
for (threadlist_ix = 0; threadlist_ix < nthreads; threadlist_ix++)
|
||||
if (sigismember (&(cygheap->threadlist[threadlist_ix]->sigwait_mask), sig))
|
||||
{
|
||||
|
@ -184,7 +200,7 @@ _threadinfo::find_tls (int sig)
|
|||
}
|
||||
|
||||
void
|
||||
_threadinfo::set_siginfo (sigpacket *pack)
|
||||
_cygtls::set_siginfo (sigpacket *pack)
|
||||
{
|
||||
infodata = pack->si;
|
||||
}
|
||||
|
@ -222,7 +238,7 @@ handle_threadlist_exception (EXCEPTION_RECORD *e, void *frame, CONTEXT *, void *
|
|||
}
|
||||
|
||||
void
|
||||
_threadinfo::init_threadlist_exceptions (exception_list *el)
|
||||
_cygtls::init_threadlist_exceptions (exception_list *el)
|
||||
{
|
||||
extern void init_exception_handler (exception_list *, exception_handler *);
|
||||
init_exception_handler (el, handle_threadlist_exception);
|
||||
|
|
|
@ -90,7 +90,7 @@ struct _local_storage
|
|||
'gentls_offsets' (<<-- start parsing here). */
|
||||
|
||||
typedef __uint32_t __stack_t;
|
||||
struct _threadinfo
|
||||
struct _cygtls
|
||||
{
|
||||
void (*func) /*gentls_offsets*/(int)/*gentls_offsets*/;
|
||||
int saved_errno;
|
||||
|
@ -108,7 +108,7 @@ struct _threadinfo
|
|||
struct pthread *tid;
|
||||
struct _reent local_clib;
|
||||
struct _local_storage locals;
|
||||
struct _threadinfo *prev, *next;
|
||||
struct _cygtls *prev, *next;
|
||||
__stack_t *stackptr;
|
||||
int sig;
|
||||
unsigned stacklock;
|
||||
|
@ -121,9 +121,9 @@ struct _threadinfo
|
|||
void init_thread (void *, DWORD (*) (void *, void *));
|
||||
static void call (DWORD (*) (void *, void *), void *);
|
||||
static void call2 (DWORD (*) (void *, void *), void *, void *) __attribute__ ((regparm (3)));
|
||||
static struct _threadinfo *find_tls (int sig);
|
||||
static struct _cygtls *find_tls (int sig);
|
||||
void remove (DWORD);
|
||||
void push (__stack_t, bool = false) __attribute__ ((regparm (3)));
|
||||
void push (__stack_t, bool) __attribute__ ((regparm (3)));
|
||||
__stack_t pop () __attribute__ ((regparm (1)));
|
||||
bool isinitialized () {return initialized == CYGTLS_INITIALIZED || initialized == CYGTLS_EXCEPTION;}
|
||||
void set_state (bool);
|
||||
|
@ -138,16 +138,19 @@ struct _threadinfo
|
|||
void set_siginfo (struct sigpacket *) __attribute__ ((regparm (3)));
|
||||
void set_threadkill () {threadkill = true;}
|
||||
void reset_threadkill () {threadkill = false;}
|
||||
int lock () __attribute__ ((regparm (1)));
|
||||
int call_signal_handler () __attribute__ ((regparm (1)));
|
||||
void fixup_after_fork () __attribute__ ((regparm (1)));
|
||||
void lock () __attribute__ ((regparm (1)));
|
||||
void unlock () __attribute__ ((regparm (1)));
|
||||
bool locked () __attribute__ ((regparm (1)));
|
||||
/*gentls_offsets*/
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
extern char *_tlsbase __asm__ ("%fs:4");
|
||||
extern char *_tlstop __asm__ ("%fs:8");
|
||||
#define _my_tls (((_threadinfo *) _tlsbase)[-1])
|
||||
extern _threadinfo *_main_tls;
|
||||
#define _my_tls (((_cygtls *) _tlsbase)[-1])
|
||||
extern _cygtls *_main_tls;
|
||||
|
||||
#define __getreent() (&_my_tls.local_clib)
|
||||
|
||||
|
|
|
@ -72,9 +72,9 @@ char NO_COPY **envp;
|
|||
|
||||
extern "C" void __sinit (_reent *);
|
||||
|
||||
_threadinfo NO_COPY *_main_tls;
|
||||
_cygtls NO_COPY *_main_tls;
|
||||
|
||||
int cygwin_finished_initializing;
|
||||
bool NO_COPY cygwin_finished_initializing;
|
||||
|
||||
/* Used in SIGTOMASK for generating a bit for insertion into a sigset_t.
|
||||
This is subtracted from the signal number prior to shifting the bit.
|
||||
|
@ -513,18 +513,16 @@ alloc_stack_hard_way (child_info_fork *ci, volatile char *b)
|
|||
static void
|
||||
alloc_stack (child_info_fork *ci)
|
||||
{
|
||||
/* FIXME: adding 16384 seems to avoid a stack copy problem during
|
||||
fork on Win95, but I don't know exactly why yet. DJ */
|
||||
volatile char b[ci->stacksize + 16384];
|
||||
|
||||
if (!VirtualQuery ((LPCVOID) &b, &sm, sizeof sm))
|
||||
if (!VirtualQuery ((LPCVOID) _tlstop, &sm, sizeof sm))
|
||||
api_fatal ("fork: couldn't get stack info, %E");
|
||||
|
||||
if (sm.AllocationBase == ci->stacktop)
|
||||
ci->stacksize = 0;
|
||||
else
|
||||
alloc_stack_hard_way (ci, b + sizeof (b) - 1);
|
||||
{
|
||||
ci->stacksize = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
alloc_stack_hard_way (ci, b + sizeof (b) - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -662,7 +660,6 @@ dll_crt0_0 ()
|
|||
}
|
||||
|
||||
device::init ();
|
||||
winpids::init ();
|
||||
do_global_ctors (&__CTOR_LIST__, 1);
|
||||
cygthread::init ();
|
||||
|
||||
|
@ -718,7 +715,7 @@ dll_crt0_0 ()
|
|||
CloseHandle (child_proc_info->pppid_handle);
|
||||
}
|
||||
|
||||
_threadinfo::init ();
|
||||
_cygtls::init ();
|
||||
|
||||
/* Initialize events */
|
||||
events_init ();
|
||||
|
@ -873,7 +870,7 @@ dll_crt0_1 (char *)
|
|||
set_console_title (cp);
|
||||
}
|
||||
|
||||
cygwin_finished_initializing = 1;
|
||||
cygwin_finished_initializing = true;
|
||||
/* Call init of loaded dlls. */
|
||||
dlls.init ();
|
||||
|
||||
|
|
|
@ -371,7 +371,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 (!cygwin_finished_initializing)
|
||||
if (!in_forkee && !cygwin_finished_initializing)
|
||||
type = DLL_LINK;
|
||||
else
|
||||
{
|
||||
|
@ -387,7 +387,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 || (cygwin_finished_initializing && !d->init ()))
|
||||
if (!d || ((in_forkee || cygwin_finished_initializing) && !d->init ()))
|
||||
return -1;
|
||||
|
||||
return (DWORD) d;
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -167,11 +167,11 @@ sync_with_child (PROCESS_INFORMATION &pi, HANDLE subproc_ready,
|
|||
*/
|
||||
if (errcode != STATUS_CONTROL_C_EXIT)
|
||||
{
|
||||
system_printf ("child %u(%p) died before initialization with status code %p",
|
||||
cygwin_pid (pi.dwProcessId), pi.hProcess, errcode);
|
||||
system_printf ("*** child state %s", s);
|
||||
system_printf ("child %u(%p) died before initialization with status code %p",
|
||||
cygwin_pid (pi.dwProcessId), pi.hProcess, errcode);
|
||||
system_printf ("*** child state %s", s);
|
||||
#ifdef DEBUGGING
|
||||
abort ();
|
||||
try_to_debug ();
|
||||
#endif
|
||||
}
|
||||
set_errno (EAGAIN);
|
||||
|
@ -212,13 +212,13 @@ sync_with_parent (const char *s, bool hang_self)
|
|||
switch (psync_rc)
|
||||
{
|
||||
case WAIT_TIMEOUT:
|
||||
api_fatal ("WFSO timed out for %s", s);
|
||||
api_fatal ("WFSO timed out %s", s);
|
||||
break;
|
||||
case WAIT_FAILED:
|
||||
if (GetLastError () == ERROR_INVALID_HANDLE &&
|
||||
WaitForSingleObject (fork_info->forker_finished, 1) != WAIT_FAILED)
|
||||
break;
|
||||
api_fatal ("WFSO failed for %s, fork_finished %p, %E", s,
|
||||
api_fatal ("WFSO failed %s, fork_finished %p, %E", s,
|
||||
fork_info->forker_finished);
|
||||
break;
|
||||
default:
|
||||
|
@ -243,6 +243,17 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
|
|||
sigproc_printf ("hParent %p, child 1 first_dll %p, load_dlls %d", hParent,
|
||||
first_dll, load_dlls);
|
||||
|
||||
/* If we've played with the stack, stacksize != 0. That means that
|
||||
fork() was invoked from other than the main thread. Make sure that
|
||||
the threadinfo information is properly set up. */
|
||||
if (!fork_info->stacksize)
|
||||
{
|
||||
_main_tls = &_my_tls;
|
||||
_main_tls->init_thread (NULL, NULL);
|
||||
_main_tls->local_clib = *_impure_ptr;
|
||||
_impure_ptr = &_main_tls->local_clib;
|
||||
}
|
||||
|
||||
#ifdef DEBUGGING
|
||||
char c;
|
||||
if (GetEnvironmentVariable ("FORKDEBUG", &c, 1))
|
||||
|
@ -257,18 +268,6 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* If we've played with the stack, stacksize != 0. That means that
|
||||
fork() was invoked from other than the main thread. Make sure that
|
||||
when the "main" thread exits it calls do_exit, like a normal process.
|
||||
Exit with a status code of 0. */
|
||||
if (fork_info->stacksize)
|
||||
{
|
||||
_main_tls = &_my_tls;
|
||||
_main_tls->init_thread (NULL, NULL);
|
||||
_main_tls->local_clib = *_impure_ptr;
|
||||
_impure_ptr = &_main_tls->local_clib;
|
||||
}
|
||||
|
||||
set_file_api_mode (current_codepage);
|
||||
|
||||
MALLOC_CHECK;
|
||||
|
@ -307,7 +306,8 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
|
|||
#endif
|
||||
|
||||
pinfo_fixup_after_fork ();
|
||||
signal_fixup_after_fork ();
|
||||
_my_tls.fixup_after_fork ();
|
||||
sigproc_init ();
|
||||
|
||||
/* Set thread local stuff to zero. Under Windows 95/98 this is sometimes
|
||||
non-zero, for some reason.
|
||||
|
@ -320,6 +320,7 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
|
|||
fixup_timers_after_fork ();
|
||||
wait_for_sigthread ();
|
||||
cygbench ("fork-child");
|
||||
cygwin_finished_initializing = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -458,7 +459,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
|
|||
|
||||
syscall_printf ("CreateProcess (%s, %s, 0, 0, 1, %x, 0, 0, %p, %p)",
|
||||
myself->progname, myself->progname, c_flags, &si, &pi);
|
||||
__malloc_lock ();
|
||||
bool locked = __malloc_lock ();
|
||||
void *newheap;
|
||||
newheap = cygheap_setup_for_child (&ch, cygheap->fdtab.need_fixup_before ());
|
||||
rc = CreateProcess (myself->progname, /* image to run */
|
||||
|
@ -483,6 +484,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
|
|||
/* Restore impersonation */
|
||||
cygheap->user.reimpersonate ();
|
||||
cygheap_setup_for_child_cleanup (newheap, &ch, 0);
|
||||
__malloc_unlock ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -573,6 +575,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
|
|||
dll_bss_start, dll_bss_end, impure_beg, impure_end, NULL);
|
||||
|
||||
__malloc_unlock ();
|
||||
locked = false;
|
||||
MALLOC_CHECK;
|
||||
if (!rc)
|
||||
goto cleanup;
|
||||
|
@ -622,6 +625,9 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
|
|||
|
||||
/* Common cleanup code for failure cases */
|
||||
cleanup:
|
||||
if (locked)
|
||||
__malloc_unlock ();
|
||||
|
||||
/* Remember to de-allocate the fd table. */
|
||||
if (pi.hProcess)
|
||||
ForceCloseHandle1 (pi.hProcess, childhProc);
|
||||
|
@ -725,7 +731,7 @@ vfork ()
|
|||
debug_printf ("cygheap->ctty_on_hold %p, cygheap->open_fhs %d", cygheap->ctty_on_hold, cygheap->open_fhs);
|
||||
int res = cygheap->fdtab.vfork_child_dup () ? 0 : -1;
|
||||
debug_printf ("%d = vfork()", res);
|
||||
call_signal_handler_now (); // FIXME: racy
|
||||
_my_tls.call_signal_handler (); // FIXME: racy
|
||||
vf->tls = _my_tls;
|
||||
return res;
|
||||
}
|
||||
|
@ -757,7 +763,7 @@ vfork ()
|
|||
debug_printf ("exiting vfork, pid %d", pid);
|
||||
sig_dispatch_pending ();
|
||||
|
||||
call_signal_handler_now (); // FIXME: racy
|
||||
_my_tls.call_signal_handler (); // FIXME: racy
|
||||
_my_tls = vf->tls;
|
||||
return pid;
|
||||
#endif
|
||||
|
|
|
@ -91,86 +91,99 @@ EOF
|
|||
|
||||
.stabs "_sigfe:F(0,1)",36,0,0,__sigbe
|
||||
__sigfe:
|
||||
pushl %ebx
|
||||
pushl %edx
|
||||
movl %fs:4,%edx
|
||||
1: movl \$1,%eax
|
||||
lock xchgl %eax,$tls::stacklock(%edx)
|
||||
cmpl %eax,%eax
|
||||
jz 2f
|
||||
xorl %eax,%eax
|
||||
call _low_priority_sleep
|
||||
jmp 1b
|
||||
2: movl \$4,%eax
|
||||
xadd %eax,$tls::stackptr(%edx)
|
||||
decl $tls::stacklock(%edx)
|
||||
leal __sigbe,%edx
|
||||
xchgl %edx,8(%esp)
|
||||
movl %edx,(%eax)
|
||||
popl %edx
|
||||
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
|
||||
orl %eax,%eax # it will be zero
|
||||
jz 2f # if so
|
||||
xorl %eax,%eax # nope. It was not zero
|
||||
call _low_priority_sleep # should be a short-time thing, so
|
||||
jmp 1b # sleep and loop
|
||||
2: movl \$4,%eax # have the lock, now increment the
|
||||
xadd %eax,$tls::stackptr(%edx) # stack pointer and get pointer
|
||||
leal __sigbe,%ebx # new place to return to
|
||||
xchgl %ebx,12(%esp) # exchange with real return value
|
||||
movl %ebx,(%eax) # store real return value on alt stack
|
||||
decl $tls::stacklock(%edx) # remove lock
|
||||
popl %edx # restore saved value
|
||||
popl %ebx
|
||||
ret
|
||||
|
||||
.global __sigbe
|
||||
.stabs "_sigbe:F(0,1)",36,0,0,__sigbe
|
||||
__sigbe:
|
||||
pushl %edx
|
||||
pushl %eax
|
||||
movl %fs:4,%edx
|
||||
1: movl \$1,%eax
|
||||
lock xchgl %eax,$tls::stacklock(%edx)
|
||||
cmpl %eax,%eax
|
||||
jz 2f
|
||||
xorl %eax,%eax
|
||||
call _low_priority_sleep
|
||||
jmp 1b
|
||||
2: movl \$-4,%eax
|
||||
xadd %eax,$tls::stackptr(%edx)
|
||||
decl $tls::stacklock(%edx)
|
||||
xchgl %edx,-4(%eax)
|
||||
xchgl %edx,4(%esp)
|
||||
pushl %ebx
|
||||
pushl %edx # return here after cygwin syscall
|
||||
pushl %eax # don't clobber
|
||||
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
|
||||
orl %eax,%eax # it will be zero
|
||||
jz 2f # if so
|
||||
xorl %eax,%eax # nope. not zero
|
||||
call _low_priority_sleep # sleep
|
||||
jmp 1b # and loop
|
||||
2: movl \$-4,%eax # now decrement aux stack
|
||||
xadd %eax,$tls::stackptr(%edx) # and get pointer
|
||||
# xorl %ebx,%ebx
|
||||
movl \$0x41774177,%ebx
|
||||
xchgl %ebx,-4(%eax) #
|
||||
xchgl %ebx,8(%esp)
|
||||
decl $tls::stacklock(%edx) # release lock
|
||||
popl %eax
|
||||
popl %edx
|
||||
ret
|
||||
|
||||
.global __ZN11_threadinfo3popEv
|
||||
__ZN11_threadinfo3popEv:
|
||||
.global __ZN7_cygtls3popEv
|
||||
__ZN7_cygtls3popEv:
|
||||
1: pushl %ebx
|
||||
pushl %edx # FIXME: needed?
|
||||
movl %eax,%edx
|
||||
movl \$-4,%ebx
|
||||
xadd %ebx,$tls::pstackptr(%edx)
|
||||
xorl %eax,%eax
|
||||
# xorl %eax,%eax
|
||||
movl 8(%esp),%eax
|
||||
xchgl %eax,-4(%ebx)
|
||||
popl %edx # FIXME: needed?
|
||||
popl %ebx
|
||||
ret
|
||||
|
||||
.global __ZN11_threadinfo4lockEv
|
||||
__ZN11_threadinfo4lockEv:
|
||||
pushl %ebx
|
||||
movl %eax,%ebx
|
||||
.global __ZN7_cygtls4lockEv
|
||||
__ZN7_cygtls4lockEv:
|
||||
pushl %edi
|
||||
movl %eax,%edi
|
||||
1: movl \$1,%eax
|
||||
lock xchgl %eax,$tls::pstacklock(%ebx)
|
||||
cmpl %eax,%eax
|
||||
lock xchgl %eax,$tls::pstacklock(%edi)
|
||||
orl %eax,%eax
|
||||
jz 2f
|
||||
xorl %eax,%eax
|
||||
call _low_priority_sleep
|
||||
jmp 1b
|
||||
2: xorl \$1,%eax
|
||||
popl %ebx
|
||||
2: popl %edi
|
||||
ret
|
||||
|
||||
.global __ZN11_threadinfo6unlockEv
|
||||
__ZN11_threadinfo6unlockEv:
|
||||
.global __ZN7_cygtls6unlockEv
|
||||
__ZN7_cygtls6unlockEv:
|
||||
decl $tls::pstacklock(%eax)
|
||||
ret
|
||||
|
||||
.global __ZN7_cygtls6lockedEv
|
||||
__ZN7_cygtls6lockedEv:
|
||||
movl $tls::pstacklock(%eax),%eax
|
||||
ret
|
||||
|
||||
.global _sigreturn
|
||||
.stabs "sigreturn:F(0,1)",36,0,0,_sigreturn
|
||||
_sigreturn:
|
||||
addl \$4,%esp # Remove argument
|
||||
addl \$4,%esp # Remove argument
|
||||
call _set_process_mask\@4
|
||||
|
||||
movl %fs:4,%ebx
|
||||
|
||||
cmpl \$0,$tls::sig(%ebx) # Did a signal come in?
|
||||
jnz 3f # Yes, if non-zero
|
||||
# cmpl \$0,$tls::sig(%ebx) # Did a signal come in?
|
||||
# jnz 3f # Yes, if non-zero
|
||||
|
||||
1: popl %edx # saved errno
|
||||
testl %edx,%edx # Is it < 0
|
||||
|
@ -215,8 +228,7 @@ _sigdelayed:
|
|||
movl \$0,$tls::sig(%ebx) # zero the signal number as a
|
||||
# flag to the signal handler thread
|
||||
# that it is ok to set up sigsave
|
||||
4: popl %ebx
|
||||
jmp *%ebx
|
||||
4: ret
|
||||
|
||||
EOF
|
||||
}
|
||||
|
@ -229,15 +241,26 @@ sub longjmp {
|
|||
.globl _longjmp
|
||||
|
||||
_longjmp:
|
||||
1: movl %fs:4,%edx
|
||||
movl \$1,%eax
|
||||
lock xchgl %eax,$tls::stacklock(%edx)
|
||||
orl %eax,%eax
|
||||
jz 2f
|
||||
xorl %eax,%eax
|
||||
call _low_priority_sleep
|
||||
jmp 1b
|
||||
2: leal ($tls::stack)(%edx),%eax
|
||||
movl %eax,($tls::stackptr)(%edx)
|
||||
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
movl 8(%ebp),%edi
|
||||
movl 12(%ebp),%eax
|
||||
testl %eax,%eax
|
||||
jne 0f
|
||||
jne 3f
|
||||
incl %eax
|
||||
0:
|
||||
movl %eax,0(%edi)
|
||||
|
||||
3: movl %eax,0(%edi)
|
||||
movl 24(%edi),%ebp
|
||||
pushfl
|
||||
popl %ebx
|
||||
|
@ -250,14 +273,12 @@ _longjmp:
|
|||
movw %ax,%es
|
||||
movw 40(%edi),%ax
|
||||
movw %ax,%gs
|
||||
movl %fs:4,%eax
|
||||
leal ($tls::stack)(%eax),%edx
|
||||
movl %edx,($tls::stackptr)(%eax)
|
||||
movl 0(%edi),%eax
|
||||
movl 4(%edi),%ebx
|
||||
movl 8(%edi),%ecx
|
||||
movl 12(%edi),%edx
|
||||
movl 16(%edi),%esi
|
||||
decl $tls::stacklock(%edx)
|
||||
movl 12(%edi),%edx
|
||||
movl 20(%edi),%edi
|
||||
popfl
|
||||
ret
|
||||
|
|
|
@ -27,7 +27,7 @@ HANDLE sync_startup;
|
|||
static void WINAPI
|
||||
threadfunc_fe (VOID *arg)
|
||||
{
|
||||
_threadinfo::call ((DWORD (*) (void *, void *)) (((char **) _tlsbase)[OLDFUNC_OFFSET]), arg);
|
||||
_cygtls::call ((DWORD (*) (void *, void *)) (((char **) _tlsbase)[OLDFUNC_OFFSET]), arg);
|
||||
}
|
||||
|
||||
static DWORD WINAPI
|
||||
|
|
|
@ -318,7 +318,7 @@ low_priority_sleep (DWORD secs)
|
|||
|
||||
if (!secs && wincap.has_switch_to_thread ())
|
||||
{
|
||||
for (int i = 0; i < 10; i++)
|
||||
for (int i = 0; i < 3; i++)
|
||||
SwitchToThread ();
|
||||
}
|
||||
else
|
||||
|
|
|
@ -58,7 +58,7 @@ class vfork_save
|
|||
public:
|
||||
int pid;
|
||||
DWORD frame[100];
|
||||
_threadinfo tls;
|
||||
_cygtls tls;
|
||||
char **vfork_ebp;
|
||||
char **vfork_esp;
|
||||
int ctty;
|
||||
|
|
|
@ -30,6 +30,7 @@ details. */
|
|||
#include "shared_info.h"
|
||||
#include "cygheap.h"
|
||||
#include "fhandler.h"
|
||||
#include "cygmalloc.h"
|
||||
|
||||
static char NO_COPY pinfo_dummy[sizeof (_pinfo)] = {0};
|
||||
|
||||
|
@ -755,22 +756,14 @@ winpids::enum9x (bool winpid)
|
|||
return nelem;
|
||||
}
|
||||
|
||||
NO_COPY CRITICAL_SECTION winpids::cs;
|
||||
|
||||
void
|
||||
winpids::set (bool winpid)
|
||||
{
|
||||
EnterCriticalSection (&cs);
|
||||
__malloc_lock ();
|
||||
npids = (this->*enum_processes) (winpid);
|
||||
if (pidlist)
|
||||
pidlist[npids] = 0;
|
||||
LeaveCriticalSection (&cs);
|
||||
}
|
||||
|
||||
void
|
||||
winpids::init ()
|
||||
{
|
||||
InitializeCriticalSection (&cs);
|
||||
__malloc_unlock ();
|
||||
}
|
||||
|
||||
DWORD
|
||||
|
|
|
@ -179,7 +179,6 @@ class winpids
|
|||
DWORD enumNT (bool winpid);
|
||||
DWORD enum9x (bool winpid);
|
||||
void add (DWORD& nelem, bool, DWORD pid);
|
||||
static CRITICAL_SECTION cs;
|
||||
public:
|
||||
DWORD npids;
|
||||
inline void reset () { npids = 0; release (); }
|
||||
|
@ -196,7 +195,6 @@ public:
|
|||
inline _pinfo *operator [] (int i) const {return (_pinfo *) pinfolist[i];}
|
||||
~winpids ();
|
||||
void release ();
|
||||
static void init ();
|
||||
};
|
||||
|
||||
extern __inline pid_t
|
||||
|
|
|
@ -93,7 +93,7 @@ nanosleep (const struct timespec *rqtp, struct timespec *rmtp)
|
|||
rem = 0;
|
||||
if (rc == WAIT_OBJECT_0)
|
||||
{
|
||||
(void) call_signal_handler_now ();
|
||||
(void) _my_tls.call_signal_handler ();
|
||||
set_errno (EINTR);
|
||||
res = -1;
|
||||
}
|
||||
|
@ -302,7 +302,7 @@ kill_pgrp (pid_t pid, siginfo_t& si)
|
|||
found++;
|
||||
}
|
||||
|
||||
if (killself && kill_worker (myself->pid, si))
|
||||
if (killself && !exit_state && kill_worker (myself->pid, si))
|
||||
res = -1;
|
||||
|
||||
if (!found)
|
||||
|
@ -341,7 +341,7 @@ abort (void)
|
|||
set_signal_mask (sig_mask);
|
||||
|
||||
raise (SIGABRT);
|
||||
(void) call_signal_handler_now (); /* Call any signal handler */
|
||||
(void) _my_tls.call_signal_handler (); /* Call any signal handler */
|
||||
do_exit (1); /* signal handler didn't exit. Goodbye. */
|
||||
}
|
||||
|
||||
|
|
|
@ -668,7 +668,7 @@ sig_send (_pinfo *p, int sig)
|
|||
If sending to this process, wait for notification that a signal has
|
||||
completed before returning. */
|
||||
int __stdcall
|
||||
sig_send (_pinfo *p, siginfo_t& si, _threadinfo *tls)
|
||||
sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
|
||||
{
|
||||
int rc = 1;
|
||||
bool its_me;
|
||||
|
@ -747,7 +747,7 @@ sig_send (_pinfo *p, siginfo_t& si, _threadinfo *tls)
|
|||
if (!pack.si.si_uid)
|
||||
pack.si.si_uid = myself->uid;
|
||||
pack.pid = myself->pid;
|
||||
pack.tls = (_threadinfo *) tls;
|
||||
pack.tls = (_cygtls *) tls;
|
||||
if (wait_for_completion)
|
||||
{
|
||||
pack.wakeup = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
|
||||
|
@ -816,7 +816,7 @@ sig_send (_pinfo *p, siginfo_t& si, _threadinfo *tls)
|
|||
}
|
||||
|
||||
if (wait_for_completion && si.si_signo != __SIGFLUSHFAST)
|
||||
call_signal_handler_now ();
|
||||
_my_tls.call_signal_handler ();
|
||||
|
||||
out:
|
||||
if (pack.wakeup)
|
||||
|
|
|
@ -54,7 +54,7 @@ struct sigpacket
|
|||
{
|
||||
siginfo_t si;
|
||||
pid_t pid;
|
||||
class _threadinfo *tls;
|
||||
class _cygtls *tls;
|
||||
sigset_t *mask;
|
||||
union
|
||||
{
|
||||
|
@ -91,9 +91,8 @@ void __stdcall subproc_init ();
|
|||
void __stdcall sigproc_terminate ();
|
||||
bool __stdcall proc_exists (_pinfo *) __attribute__ ((regparm(1)));
|
||||
bool __stdcall pid_exists (pid_t) __attribute__ ((regparm(1)));
|
||||
int __stdcall sig_send (_pinfo *, siginfo_t&, class _threadinfo *tls = NULL) __attribute__ ((regparm (3)));
|
||||
int __stdcall sig_send (_pinfo *, siginfo_t&, class _cygtls *tls = NULL) __attribute__ ((regparm (3)));
|
||||
int __stdcall sig_send (_pinfo *, int) __attribute__ ((regparm (2)));
|
||||
void __stdcall signal_fixup_after_fork ();
|
||||
void __stdcall signal_fixup_after_exec ();
|
||||
void __stdcall wait_for_sigthread ();
|
||||
void __stdcall sigalloc ();
|
||||
|
|
|
@ -69,8 +69,10 @@ int
|
|||
muto::acquire (DWORD ms)
|
||||
{
|
||||
DWORD this_tid = GetCurrentThreadId ();
|
||||
#if 0
|
||||
if (exiting_thread)
|
||||
return this_tid == exiting_thread;
|
||||
#endif
|
||||
|
||||
if (tid != this_tid)
|
||||
{
|
||||
|
@ -113,8 +115,6 @@ int
|
|||
muto::release ()
|
||||
{
|
||||
DWORD this_tid = GetCurrentThreadId ();
|
||||
if (exiting_thread)
|
||||
return this_tid == exiting_thread;
|
||||
|
||||
if (tid != this_tid || !visits)
|
||||
{
|
||||
|
|
|
@ -461,7 +461,7 @@ readv (int fd, const struct iovec *const iov, const int iovcnt)
|
|||
}
|
||||
|
||||
out:
|
||||
if (res >= 0 || get_errno () != EINTR || !call_signal_handler_now ())
|
||||
if (res >= 0 || get_errno () != EINTR || !_my_tls.call_signal_handler ())
|
||||
break;
|
||||
set_errno (e);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ details. */
|
|||
#include "cygwin/version.h"
|
||||
#include "perprocess.h"
|
||||
#include "sigproc.h"
|
||||
#include "cygtls.h"
|
||||
#include <sys/termios.h>
|
||||
|
||||
/* tcsendbreak: POSIX 7.2.2.1 */
|
||||
|
@ -146,7 +147,7 @@ tcsetattr (int fd, int a, const struct termios *t)
|
|||
e = get_errno ();
|
||||
break;
|
||||
case bg_signalled:
|
||||
if (call_signal_handler_now ())
|
||||
if (_my_tls.call_signal_handler ())
|
||||
continue;
|
||||
res = -1;
|
||||
/* fall through intentionally */
|
||||
|
|
|
@ -348,7 +348,7 @@ private:
|
|||
|
||||
#define WAIT_CANCELED (WAIT_OBJECT_0 + 1)
|
||||
|
||||
class _threadinfo;
|
||||
class _cygtls;
|
||||
class pthread: public verifyable_object
|
||||
{
|
||||
public:
|
||||
|
@ -360,7 +360,7 @@ public:
|
|||
bool valid;
|
||||
bool suspended;
|
||||
int cancelstate, canceltype;
|
||||
_threadinfo *cygtls;
|
||||
_cygtls *cygtls;
|
||||
HANDLE cancel_event;
|
||||
pthread_t joiner;
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ details. */
|
|||
#include "sigproc.h"
|
||||
#include "perthread.h"
|
||||
#include "thread.h"
|
||||
#include "cygtls.h"
|
||||
|
||||
/* This is called _wait and not wait because the real wait is defined
|
||||
in libc/syscalls/syswait.c. It calls us. */
|
||||
|
@ -99,7 +100,7 @@ wait4 (int intpid, int *status, int options, struct rusage *r)
|
|||
if (w->status == -1)
|
||||
{
|
||||
set_sig_errno (EINTR);
|
||||
call_signal_handler_now ();
|
||||
_my_tls.call_signal_handler ();
|
||||
sawsig = true;
|
||||
res = -1;
|
||||
}
|
||||
|
@ -114,7 +115,7 @@ wait4 (int intpid, int *status, int options, struct rusage *r)
|
|||
*status = w->status;
|
||||
|
||||
done:
|
||||
if (!sawsig || !call_signal_handler_now ())
|
||||
if (!sawsig || !_my_tls.call_signal_handler ())
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -239,7 +239,7 @@ extern "C" int try_to_debug (bool waitloop = 1);
|
|||
|
||||
void set_file_api_mode (codepage_type);
|
||||
|
||||
extern int cygwin_finished_initializing;
|
||||
extern bool cygwin_finished_initializing;
|
||||
|
||||
/**************************** Miscellaneous ******************************/
|
||||
|
||||
|
|
Loading…
Reference in New Issue