mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-21 16:26:12 +08:00
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>
|
2004-02-11 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* security.cc (get_nt_object_attribute): Fix error handling.
|
* security.cc (get_nt_object_attribute): Fix error handling.
|
||||||
|
@ -266,7 +266,7 @@ struct init_cygheap
|
|||||||
#ifdef NEWVFORK
|
#ifdef NEWVFORK
|
||||||
fhandler_tty_slave *ctty_on_hold;
|
fhandler_tty_slave *ctty_on_hold;
|
||||||
#endif
|
#endif
|
||||||
struct _threadinfo **threadlist;
|
struct _cygtls **threadlist;
|
||||||
size_t sthreads;
|
size_t sthreads;
|
||||||
int open_fhs;
|
int open_fhs;
|
||||||
void close_ctty ();
|
void close_ctty ();
|
||||||
|
@ -20,6 +20,7 @@ details. */
|
|||||||
#include "dtable.h"
|
#include "dtable.h"
|
||||||
#include "cygheap.h"
|
#include "cygheap.h"
|
||||||
#include "cygthread.h"
|
#include "cygthread.h"
|
||||||
|
#include "pinfo.h"
|
||||||
#include "sigproc.h"
|
#include "sigproc.h"
|
||||||
|
|
||||||
class sentry
|
class sentry
|
||||||
@ -32,7 +33,7 @@ public:
|
|||||||
sentry () {destroy = 0;}
|
sentry () {destroy = 0;}
|
||||||
sentry (DWORD wait) {destroy = lock->acquire (wait);}
|
sentry (DWORD wait) {destroy = lock->acquire (wait);}
|
||||||
~sentry () {if (destroy) lock->release ();}
|
~sentry () {if (destroy) lock->release ();}
|
||||||
friend void _threadinfo::init ();
|
friend void _cygtls::init ();
|
||||||
};
|
};
|
||||||
|
|
||||||
muto NO_COPY *sentry::lock;
|
muto NO_COPY *sentry::lock;
|
||||||
@ -42,27 +43,27 @@ static size_t NO_COPY nthreads;
|
|||||||
#define THREADLIST_CHUNK 256
|
#define THREADLIST_CHUNK 256
|
||||||
|
|
||||||
void
|
void
|
||||||
_threadinfo::init ()
|
_cygtls::init ()
|
||||||
{
|
{
|
||||||
if (cygheap->threadlist)
|
if (cygheap->threadlist)
|
||||||
memset (cygheap->threadlist, 0, cygheap->sthreads * sizeof (cygheap->threadlist[0]));
|
memset (cygheap->threadlist, 0, cygheap->sthreads * sizeof (cygheap->threadlist[0]));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cygheap->sthreads = THREADLIST_CHUNK;
|
cygheap->sthreads = THREADLIST_CHUNK;
|
||||||
cygheap->threadlist = (_threadinfo **) ccalloc (HEAP_TLS, cygheap->sthreads,
|
cygheap->threadlist = (_cygtls **) ccalloc (HEAP_TLS, cygheap->sthreads,
|
||||||
sizeof (cygheap->threadlist[0]));
|
sizeof (cygheap->threadlist[0]));
|
||||||
}
|
}
|
||||||
new_muto1 (sentry::lock, sentry_lock);
|
new_muto1 (sentry::lock, sentry_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_threadinfo::set_state (bool is_exception)
|
_cygtls::set_state (bool is_exception)
|
||||||
{
|
{
|
||||||
initialized = CYGTLS_INITIALIZED + is_exception;
|
initialized = CYGTLS_INITIALIZED + is_exception;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_threadinfo::reset_exception ()
|
_cygtls::reset_exception ()
|
||||||
{
|
{
|
||||||
if (initialized == CYGTLS_EXCEPTION)
|
if (initialized == CYGTLS_EXCEPTION)
|
||||||
{
|
{
|
||||||
@ -75,14 +76,14 @@ _threadinfo::reset_exception ()
|
|||||||
|
|
||||||
/* Two calls to get the stack right... */
|
/* Two calls to get the stack right... */
|
||||||
void
|
void
|
||||||
_threadinfo::call (DWORD (*func) (void *, void *), void *arg)
|
_cygtls::call (DWORD (*func) (void *, void *), void *arg)
|
||||||
{
|
{
|
||||||
char buf[CYGTLS_PADSIZE];
|
char buf[CYGTLS_PADSIZE];
|
||||||
call2 (func, arg, buf);
|
call2 (func, arg, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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;
|
exception_list except_entry;
|
||||||
/* Initialize this thread's ability to respond to things like
|
/* 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
|
void
|
||||||
_threadinfo::init_thread (void *x, DWORD (*func) (void *, void *))
|
_cygtls::init_thread (void *x, DWORD (*func) (void *, void *))
|
||||||
{
|
{
|
||||||
if (x)
|
if (x)
|
||||||
{
|
{
|
||||||
@ -125,7 +126,7 @@ _threadinfo::init_thread (void *x, DWORD (*func) (void *, void *))
|
|||||||
sentry here (INFINITE);
|
sentry here (INFINITE);
|
||||||
if (nthreads >= cygheap->sthreads)
|
if (nthreads >= cygheap->sthreads)
|
||||||
{
|
{
|
||||||
cygheap->threadlist = (_threadinfo **)
|
cygheap->threadlist = (_cygtls **)
|
||||||
crealloc (cygheap->threadlist, (cygheap->sthreads += THREADLIST_CHUNK)
|
crealloc (cygheap->threadlist, (cygheap->sthreads += THREADLIST_CHUNK)
|
||||||
* sizeof (cygheap->threadlist[0]));
|
* sizeof (cygheap->threadlist[0]));
|
||||||
memset (cygheap->threadlist + nthreads, 0, 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
|
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);
|
debug_printf ("wait %p\n", wait);
|
||||||
sentry here (wait);
|
sentry here (wait);
|
||||||
@ -153,7 +169,7 @@ _threadinfo::remove (DWORD wait)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_threadinfo::push (__stack_t addr, bool exception)
|
_cygtls::push (__stack_t addr, bool exception)
|
||||||
{
|
{
|
||||||
if (exception)
|
if (exception)
|
||||||
lock ();
|
lock ();
|
||||||
@ -166,13 +182,13 @@ _threadinfo::push (__stack_t addr, bool exception)
|
|||||||
#define BAD_IX ((size_t) -1)
|
#define BAD_IX ((size_t) -1)
|
||||||
static size_t NO_COPY threadlist_ix = BAD_IX;
|
static size_t NO_COPY threadlist_ix = BAD_IX;
|
||||||
|
|
||||||
_threadinfo *
|
_cygtls *
|
||||||
_threadinfo::find_tls (int sig)
|
_cygtls::find_tls (int sig)
|
||||||
{
|
{
|
||||||
debug_printf ("sig %d\n", sig);
|
debug_printf ("sig %d\n", sig);
|
||||||
sentry here (INFINITE);
|
sentry here (INFINITE);
|
||||||
__asm__ volatile (".equ _threadlist_exception_return,.");
|
__asm__ volatile (".equ _threadlist_exception_return,.");
|
||||||
_threadinfo *res = NULL;
|
_cygtls *res = NULL;
|
||||||
for (threadlist_ix = 0; threadlist_ix < nthreads; threadlist_ix++)
|
for (threadlist_ix = 0; threadlist_ix < nthreads; threadlist_ix++)
|
||||||
if (sigismember (&(cygheap->threadlist[threadlist_ix]->sigwait_mask), sig))
|
if (sigismember (&(cygheap->threadlist[threadlist_ix]->sigwait_mask), sig))
|
||||||
{
|
{
|
||||||
@ -184,7 +200,7 @@ _threadinfo::find_tls (int sig)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_threadinfo::set_siginfo (sigpacket *pack)
|
_cygtls::set_siginfo (sigpacket *pack)
|
||||||
{
|
{
|
||||||
infodata = pack->si;
|
infodata = pack->si;
|
||||||
}
|
}
|
||||||
@ -222,7 +238,7 @@ handle_threadlist_exception (EXCEPTION_RECORD *e, void *frame, CONTEXT *, void *
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 *);
|
extern void init_exception_handler (exception_list *, exception_handler *);
|
||||||
init_exception_handler (el, handle_threadlist_exception);
|
init_exception_handler (el, handle_threadlist_exception);
|
||||||
|
@ -90,7 +90,7 @@ struct _local_storage
|
|||||||
'gentls_offsets' (<<-- start parsing here). */
|
'gentls_offsets' (<<-- start parsing here). */
|
||||||
|
|
||||||
typedef __uint32_t __stack_t;
|
typedef __uint32_t __stack_t;
|
||||||
struct _threadinfo
|
struct _cygtls
|
||||||
{
|
{
|
||||||
void (*func) /*gentls_offsets*/(int)/*gentls_offsets*/;
|
void (*func) /*gentls_offsets*/(int)/*gentls_offsets*/;
|
||||||
int saved_errno;
|
int saved_errno;
|
||||||
@ -108,7 +108,7 @@ struct _threadinfo
|
|||||||
struct pthread *tid;
|
struct pthread *tid;
|
||||||
struct _reent local_clib;
|
struct _reent local_clib;
|
||||||
struct _local_storage locals;
|
struct _local_storage locals;
|
||||||
struct _threadinfo *prev, *next;
|
struct _cygtls *prev, *next;
|
||||||
__stack_t *stackptr;
|
__stack_t *stackptr;
|
||||||
int sig;
|
int sig;
|
||||||
unsigned stacklock;
|
unsigned stacklock;
|
||||||
@ -121,9 +121,9 @@ struct _threadinfo
|
|||||||
void init_thread (void *, DWORD (*) (void *, void *));
|
void init_thread (void *, DWORD (*) (void *, void *));
|
||||||
static void call (DWORD (*) (void *, void *), void *);
|
static void call (DWORD (*) (void *, void *), void *);
|
||||||
static void call2 (DWORD (*) (void *, void *), void *, void *) __attribute__ ((regparm (3)));
|
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 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)));
|
__stack_t pop () __attribute__ ((regparm (1)));
|
||||||
bool isinitialized () {return initialized == CYGTLS_INITIALIZED || initialized == CYGTLS_EXCEPTION;}
|
bool isinitialized () {return initialized == CYGTLS_INITIALIZED || initialized == CYGTLS_EXCEPTION;}
|
||||||
void set_state (bool);
|
void set_state (bool);
|
||||||
@ -138,16 +138,19 @@ struct _threadinfo
|
|||||||
void set_siginfo (struct sigpacket *) __attribute__ ((regparm (3)));
|
void set_siginfo (struct sigpacket *) __attribute__ ((regparm (3)));
|
||||||
void set_threadkill () {threadkill = true;}
|
void set_threadkill () {threadkill = true;}
|
||||||
void reset_threadkill () {threadkill = false;}
|
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)));
|
void unlock () __attribute__ ((regparm (1)));
|
||||||
|
bool locked () __attribute__ ((regparm (1)));
|
||||||
/*gentls_offsets*/
|
/*gentls_offsets*/
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
extern char *_tlsbase __asm__ ("%fs:4");
|
extern char *_tlsbase __asm__ ("%fs:4");
|
||||||
extern char *_tlstop __asm__ ("%fs:8");
|
extern char *_tlstop __asm__ ("%fs:8");
|
||||||
#define _my_tls (((_threadinfo *) _tlsbase)[-1])
|
#define _my_tls (((_cygtls *) _tlsbase)[-1])
|
||||||
extern _threadinfo *_main_tls;
|
extern _cygtls *_main_tls;
|
||||||
|
|
||||||
#define __getreent() (&_my_tls.local_clib)
|
#define __getreent() (&_my_tls.local_clib)
|
||||||
|
|
||||||
|
@ -72,9 +72,9 @@ char NO_COPY **envp;
|
|||||||
|
|
||||||
extern "C" void __sinit (_reent *);
|
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.
|
/* 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.
|
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
|
static void
|
||||||
alloc_stack (child_info_fork *ci)
|
alloc_stack (child_info_fork *ci)
|
||||||
{
|
{
|
||||||
/* FIXME: adding 16384 seems to avoid a stack copy problem during
|
if (!VirtualQuery ((LPCVOID) _tlstop, &sm, sizeof sm))
|
||||||
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))
|
|
||||||
api_fatal ("fork: couldn't get stack info, %E");
|
api_fatal ("fork: couldn't get stack info, %E");
|
||||||
|
|
||||||
if (sm.AllocationBase == ci->stacktop)
|
if (sm.AllocationBase == ci->stacktop)
|
||||||
ci->stacksize = 0;
|
{
|
||||||
else
|
ci->stacksize = 0;
|
||||||
alloc_stack_hard_way (ci, b + sizeof (b) - 1);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
alloc_stack_hard_way (ci, b + sizeof (b) - 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -662,7 +660,6 @@ dll_crt0_0 ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
device::init ();
|
device::init ();
|
||||||
winpids::init ();
|
|
||||||
do_global_ctors (&__CTOR_LIST__, 1);
|
do_global_ctors (&__CTOR_LIST__, 1);
|
||||||
cygthread::init ();
|
cygthread::init ();
|
||||||
|
|
||||||
@ -718,7 +715,7 @@ dll_crt0_0 ()
|
|||||||
CloseHandle (child_proc_info->pppid_handle);
|
CloseHandle (child_proc_info->pppid_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
_threadinfo::init ();
|
_cygtls::init ();
|
||||||
|
|
||||||
/* Initialize events */
|
/* Initialize events */
|
||||||
events_init ();
|
events_init ();
|
||||||
@ -873,7 +870,7 @@ dll_crt0_1 (char *)
|
|||||||
set_console_title (cp);
|
set_console_title (cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
cygwin_finished_initializing = 1;
|
cygwin_finished_initializing = true;
|
||||||
/* Call init of loaded dlls. */
|
/* Call init of loaded dlls. */
|
||||||
dlls.init ();
|
dlls.init ();
|
||||||
|
|
||||||
|
@ -371,7 +371,7 @@ dll_dllcrt0 (HMODULE h, per_process *p)
|
|||||||
initializing, then the DLL must be a cygwin-aware DLL
|
initializing, then the DLL must be a cygwin-aware DLL
|
||||||
that was explicitly linked into the program rather than
|
that was explicitly linked into the program rather than
|
||||||
a dlopened DLL. */
|
a dlopened DLL. */
|
||||||
if (!cygwin_finished_initializing)
|
if (!in_forkee && !cygwin_finished_initializing)
|
||||||
type = DLL_LINK;
|
type = DLL_LINK;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -387,7 +387,7 @@ dll_dllcrt0 (HMODULE h, per_process *p)
|
|||||||
initialize the DLL. If we haven't finished initializing,
|
initialize the DLL. If we haven't finished initializing,
|
||||||
it may not be safe to call the dll's "main" since not
|
it may not be safe to call the dll's "main" since not
|
||||||
all of cygwin's internal structures may have been set up. */
|
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 -1;
|
||||||
|
|
||||||
return (DWORD) d;
|
return (DWORD) d;
|
||||||
|
@ -519,7 +519,7 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!myself->progname[0]
|
if (!cygwin_finished_initializing
|
||||||
|| GetCurrentThreadId () == sigtid
|
|| GetCurrentThreadId () == sigtid
|
||||||
|| (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_DFL
|
|| (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_DFL
|
||||||
|| (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_IGN
|
|| (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_IGN
|
||||||
@ -692,10 +692,10 @@ interruptible (DWORD pc)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
void __stdcall
|
void __stdcall
|
||||||
_threadinfo::interrupt_setup (int sig, void *handler,
|
_cygtls::interrupt_setup (int sig, void *handler,
|
||||||
struct sigaction& siga)
|
struct sigaction& siga)
|
||||||
{
|
{
|
||||||
push ((__stack_t) sigdelayed);
|
push ((__stack_t) sigdelayed, false);
|
||||||
oldmask = myself->getsigmask ();
|
oldmask = myself->getsigmask ();
|
||||||
newmask = oldmask | siga.sa_mask | SIGTOMASK (sig);
|
newmask = oldmask | siga.sa_mask | SIGTOMASK (sig);
|
||||||
sa_flags = siga.sa_flags;
|
sa_flags = siga.sa_flags;
|
||||||
@ -717,28 +717,16 @@ _threadinfo::interrupt_setup (int sig, void *handler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
_threadinfo::interrupt_now (CONTEXT *ctx, int sig, void *handler,
|
_cygtls::interrupt_now (CONTEXT *ctx, int sig, void *handler,
|
||||||
struct sigaction& siga)
|
struct sigaction& siga)
|
||||||
{
|
{
|
||||||
push ((__stack_t) ctx->Eip);
|
push ((__stack_t) ctx->Eip, false);
|
||||||
interrupt_setup (sig, handler, siga);
|
interrupt_setup (sig, handler, siga);
|
||||||
ctx->Eip = pop ();
|
ctx->Eip = pop ();
|
||||||
SetThreadContext (*this, ctx); /* Restart the thread in a new location */
|
SetThreadContext (*this, ctx); /* Restart the thread in a new location */
|
||||||
return 1;
|
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
|
extern "C" void __stdcall
|
||||||
set_sig_errno (int e)
|
set_sig_errno (int e)
|
||||||
{
|
{
|
||||||
@ -747,13 +735,14 @@ set_sig_errno (int e)
|
|||||||
// sigproc_printf ("errno %d", 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)));
|
__attribute__((regparm(3)));
|
||||||
static int
|
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;
|
CONTEXT cx;
|
||||||
bool interrupted = false;
|
bool interrupted = false;
|
||||||
|
bool locked = false;
|
||||||
|
|
||||||
if (tls->sig)
|
if (tls->sig)
|
||||||
{
|
{
|
||||||
@ -762,12 +751,11 @@ setup_handler (int sig, void *handler, struct sigaction& siga, _threadinfo *tls)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
int locked;
|
|
||||||
for (int i = 0; i < CALL_HANDLER_RETRY; i++)
|
for (int i = 0; i < CALL_HANDLER_RETRY; i++)
|
||||||
{
|
{
|
||||||
locked = tls->lock ();
|
tls->lock ();
|
||||||
__stack_t *retaddr_on_stack = tls->stackptr - 1;
|
locked = true;
|
||||||
if (retaddr_on_stack >= tls->stack)
|
if (tls->stackptr > tls->stack)
|
||||||
{
|
{
|
||||||
tls->reset_exception ();
|
tls->reset_exception ();
|
||||||
tls->interrupt_setup (sig, handler, siga);
|
tls->interrupt_setup (sig, handler, siga);
|
||||||
@ -776,14 +764,14 @@ setup_handler (int sig, void *handler, struct sigaction& siga, _threadinfo *tls)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tls->unlock ();
|
||||||
|
locked = false;
|
||||||
DWORD res;
|
DWORD res;
|
||||||
HANDLE hth = (HANDLE) *tls;
|
HANDLE hth = (HANDLE) *tls;
|
||||||
|
|
||||||
/* Suspend the thread which will receive the signal. But first ensure that
|
/* Suspend the thread which will receive the signal.
|
||||||
this thread doesn't have any mutos. (FIXME: Someday we should just grab
|
For Windows 95, we also have to ensure that the addresses returned by
|
||||||
all of the mutos rather than checking for them)
|
GetThreadContext are valid.
|
||||||
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
|
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
|
since we don't want to stall the signal handler. FIXME: Will this result in
|
||||||
noticeable delays?
|
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);
|
sigproc_printf ("suspending mainthread PC %p", cx.Eip);
|
||||||
#endif
|
#endif
|
||||||
res = SuspendThread (hth);
|
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 */
|
/* Just set pending if thread is already suspended */
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
(void) ResumeThread (hth);
|
(void) ResumeThread (hth);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (!tls->locked ())
|
||||||
// FIXME - add check for reentering of DLL here
|
{
|
||||||
|
cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
|
||||||
cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
|
if (!GetThreadContext (hth, &cx))
|
||||||
if (!GetThreadContext (hth, &cx))
|
system_printf ("couldn't get context of main thread, %E");
|
||||||
system_printf ("couldn't get context of main thread, %E");
|
else if (interruptible (cx.Eip))
|
||||||
else if (interruptible (cx.Eip))
|
interrupted = tls->interrupt_now (&cx, sig, handler, siga);
|
||||||
interrupted = tls->interrupt_now (&cx, sig, handler, siga);
|
}
|
||||||
|
|
||||||
res = ResumeThread (hth);
|
res = ResumeThread (hth);
|
||||||
if (interrupted)
|
if (interrupted)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
tls->unlock ();
|
|
||||||
locked = false;
|
|
||||||
sigproc_printf ("couldn't interrupt. trying again.");
|
sigproc_printf ("couldn't interrupt. trying again.");
|
||||||
low_priority_sleep (0);
|
low_priority_sleep (0);
|
||||||
}
|
}
|
||||||
@ -845,6 +827,10 @@ static BOOL WINAPI
|
|||||||
ctrl_c_handler (DWORD type)
|
ctrl_c_handler (DWORD type)
|
||||||
{
|
{
|
||||||
static bool saw_close;
|
static bool saw_close;
|
||||||
|
|
||||||
|
if (!cygwin_finished_initializing)
|
||||||
|
ExitProcess (STATUS_CONTROL_C_EXIT);
|
||||||
|
|
||||||
_my_tls.remove (INFINITE);
|
_my_tls.remove (INFINITE);
|
||||||
|
|
||||||
/* Return FALSE to prevent an "End task" dialog box from appearing
|
/* Return FALSE to prevent an "End task" dialog box from appearing
|
||||||
@ -977,7 +963,7 @@ sigpacket::process ()
|
|||||||
/* nothing to do */;
|
/* nothing to do */;
|
||||||
else if (tls && sigismember (&tls->sigwait_mask, si.si_signo))
|
else if (tls && sigismember (&tls->sigwait_mask, si.si_signo))
|
||||||
insigwait_mask = true;
|
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;
|
insigwait_mask = true;
|
||||||
else if (!(masked = sigismember (mask, si.si_signo)) && tls)
|
else if (!(masked = sigismember (mask, si.si_signo)) && tls)
|
||||||
masked = sigismember (&tls->sigmask, si.si_signo);
|
masked = sigismember (&tls->sigmask, si.si_signo);
|
||||||
@ -1153,36 +1139,36 @@ events_terminate (void)
|
|||||||
exit_already = 1;
|
exit_already = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
int
|
||||||
int __stdcall
|
_cygtls::call_signal_handler ()
|
||||||
call_signal_handler_now ()
|
|
||||||
{
|
{
|
||||||
int sa_flags = 0;
|
int this_sa_flags = 0;
|
||||||
while (_my_tls.sig && _my_tls.stackptr > _my_tls.stack)
|
/* Call signal handler. No need to set stacklock since sig effectively
|
||||||
|
implies that. */
|
||||||
|
while (sig)
|
||||||
{
|
{
|
||||||
sa_flags = _my_tls.sa_flags;
|
this_sa_flags = sa_flags;
|
||||||
int sig = _my_tls.sig;
|
int thissig = sig;
|
||||||
void (*sigfunc) (int) = _my_tls.func;
|
void (*sigfunc) (int) = func;
|
||||||
|
|
||||||
(void) _my_tls.pop ();
|
(void) pop ();
|
||||||
reset_signal_arrived ();
|
reset_signal_arrived ();
|
||||||
sigset_t oldmask = _my_tls.oldmask;
|
sigset_t oldmask = oldmask;
|
||||||
int this_errno = _my_tls.saved_errno;
|
int this_errno = saved_errno;
|
||||||
set_process_mask (_my_tls.newmask);
|
set_process_mask (newmask);
|
||||||
_my_tls.sig = 0;
|
sig = 0;
|
||||||
sigfunc (sig);
|
sigfunc (thissig);
|
||||||
set_process_mask (oldmask);
|
set_process_mask (oldmask);
|
||||||
if (this_errno >= 0)
|
if (this_errno >= 0)
|
||||||
set_errno (this_errno);
|
set_errno (this_errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sa_flags & SA_RESTART;
|
return this_sa_flags & SA_RESTART;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __stdcall
|
extern "C" void __stdcall
|
||||||
reset_signal_arrived ()
|
reset_signal_arrived ()
|
||||||
{
|
{
|
||||||
(void) ResetEvent (signal_arrived);
|
(void) ResetEvent (signal_arrived);
|
||||||
sigproc_printf ("reset 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)
|
if (errcode != STATUS_CONTROL_C_EXIT)
|
||||||
{
|
{
|
||||||
system_printf ("child %u(%p) died before initialization with status code %p",
|
system_printf ("child %u(%p) died before initialization with status code %p",
|
||||||
cygwin_pid (pi.dwProcessId), pi.hProcess, errcode);
|
cygwin_pid (pi.dwProcessId), pi.hProcess, errcode);
|
||||||
system_printf ("*** child state %s", s);
|
system_printf ("*** child state %s", s);
|
||||||
#ifdef DEBUGGING
|
#ifdef DEBUGGING
|
||||||
abort ();
|
try_to_debug ();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
set_errno (EAGAIN);
|
set_errno (EAGAIN);
|
||||||
@ -212,13 +212,13 @@ sync_with_parent (const char *s, bool hang_self)
|
|||||||
switch (psync_rc)
|
switch (psync_rc)
|
||||||
{
|
{
|
||||||
case WAIT_TIMEOUT:
|
case WAIT_TIMEOUT:
|
||||||
api_fatal ("WFSO timed out for %s", s);
|
api_fatal ("WFSO timed out %s", s);
|
||||||
break;
|
break;
|
||||||
case WAIT_FAILED:
|
case WAIT_FAILED:
|
||||||
if (GetLastError () == ERROR_INVALID_HANDLE &&
|
if (GetLastError () == ERROR_INVALID_HANDLE &&
|
||||||
WaitForSingleObject (fork_info->forker_finished, 1) != WAIT_FAILED)
|
WaitForSingleObject (fork_info->forker_finished, 1) != WAIT_FAILED)
|
||||||
break;
|
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);
|
fork_info->forker_finished);
|
||||||
break;
|
break;
|
||||||
default:
|
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,
|
sigproc_printf ("hParent %p, child 1 first_dll %p, load_dlls %d", hParent,
|
||||||
first_dll, load_dlls);
|
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
|
#ifdef DEBUGGING
|
||||||
char c;
|
char c;
|
||||||
if (GetEnvironmentVariable ("FORKDEBUG", &c, 1))
|
if (GetEnvironmentVariable ("FORKDEBUG", &c, 1))
|
||||||
@ -257,18 +268,6 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
|
|||||||
}
|
}
|
||||||
#endif
|
#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);
|
set_file_api_mode (current_codepage);
|
||||||
|
|
||||||
MALLOC_CHECK;
|
MALLOC_CHECK;
|
||||||
@ -307,7 +306,8 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
pinfo_fixup_after_fork ();
|
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
|
/* Set thread local stuff to zero. Under Windows 95/98 this is sometimes
|
||||||
non-zero, for some reason.
|
non-zero, for some reason.
|
||||||
@ -320,6 +320,7 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
|
|||||||
fixup_timers_after_fork ();
|
fixup_timers_after_fork ();
|
||||||
wait_for_sigthread ();
|
wait_for_sigthread ();
|
||||||
cygbench ("fork-child");
|
cygbench ("fork-child");
|
||||||
|
cygwin_finished_initializing = true;
|
||||||
return 0;
|
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)",
|
syscall_printf ("CreateProcess (%s, %s, 0, 0, 1, %x, 0, 0, %p, %p)",
|
||||||
myself->progname, myself->progname, c_flags, &si, &pi);
|
myself->progname, myself->progname, c_flags, &si, &pi);
|
||||||
__malloc_lock ();
|
bool locked = __malloc_lock ();
|
||||||
void *newheap;
|
void *newheap;
|
||||||
newheap = cygheap_setup_for_child (&ch, cygheap->fdtab.need_fixup_before ());
|
newheap = cygheap_setup_for_child (&ch, cygheap->fdtab.need_fixup_before ());
|
||||||
rc = CreateProcess (myself->progname, /* image to run */
|
rc = CreateProcess (myself->progname, /* image to run */
|
||||||
@ -483,6 +484,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
|
|||||||
/* Restore impersonation */
|
/* Restore impersonation */
|
||||||
cygheap->user.reimpersonate ();
|
cygheap->user.reimpersonate ();
|
||||||
cygheap_setup_for_child_cleanup (newheap, &ch, 0);
|
cygheap_setup_for_child_cleanup (newheap, &ch, 0);
|
||||||
|
__malloc_unlock ();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -573,6 +575,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
|
|||||||
dll_bss_start, dll_bss_end, impure_beg, impure_end, NULL);
|
dll_bss_start, dll_bss_end, impure_beg, impure_end, NULL);
|
||||||
|
|
||||||
__malloc_unlock ();
|
__malloc_unlock ();
|
||||||
|
locked = false;
|
||||||
MALLOC_CHECK;
|
MALLOC_CHECK;
|
||||||
if (!rc)
|
if (!rc)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -622,6 +625,9 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
|
|||||||
|
|
||||||
/* Common cleanup code for failure cases */
|
/* Common cleanup code for failure cases */
|
||||||
cleanup:
|
cleanup:
|
||||||
|
if (locked)
|
||||||
|
__malloc_unlock ();
|
||||||
|
|
||||||
/* Remember to de-allocate the fd table. */
|
/* Remember to de-allocate the fd table. */
|
||||||
if (pi.hProcess)
|
if (pi.hProcess)
|
||||||
ForceCloseHandle1 (pi.hProcess, childhProc);
|
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);
|
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;
|
int res = cygheap->fdtab.vfork_child_dup () ? 0 : -1;
|
||||||
debug_printf ("%d = vfork()", res);
|
debug_printf ("%d = vfork()", res);
|
||||||
call_signal_handler_now (); // FIXME: racy
|
_my_tls.call_signal_handler (); // FIXME: racy
|
||||||
vf->tls = _my_tls;
|
vf->tls = _my_tls;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -757,7 +763,7 @@ vfork ()
|
|||||||
debug_printf ("exiting vfork, pid %d", pid);
|
debug_printf ("exiting vfork, pid %d", pid);
|
||||||
sig_dispatch_pending ();
|
sig_dispatch_pending ();
|
||||||
|
|
||||||
call_signal_handler_now (); // FIXME: racy
|
_my_tls.call_signal_handler (); // FIXME: racy
|
||||||
_my_tls = vf->tls;
|
_my_tls = vf->tls;
|
||||||
return pid;
|
return pid;
|
||||||
#endif
|
#endif
|
||||||
|
@ -91,86 +91,99 @@ EOF
|
|||||||
|
|
||||||
.stabs "_sigfe:F(0,1)",36,0,0,__sigbe
|
.stabs "_sigfe:F(0,1)",36,0,0,__sigbe
|
||||||
__sigfe:
|
__sigfe:
|
||||||
|
pushl %ebx
|
||||||
pushl %edx
|
pushl %edx
|
||||||
movl %fs:4,%edx
|
1: movl %fs:4,%edx # location of bottom of stack
|
||||||
1: movl \$1,%eax
|
movl \$1,%eax # potential lock value
|
||||||
lock xchgl %eax,$tls::stacklock(%edx)
|
lock xchgl %eax,$tls::stacklock(%edx) # see if we can grab it
|
||||||
cmpl %eax,%eax
|
orl %eax,%eax # it will be zero
|
||||||
jz 2f
|
jz 2f # if so
|
||||||
xorl %eax,%eax
|
xorl %eax,%eax # nope. It was not zero
|
||||||
call _low_priority_sleep
|
call _low_priority_sleep # should be a short-time thing, so
|
||||||
jmp 1b
|
jmp 1b # sleep and loop
|
||||||
2: movl \$4,%eax
|
2: movl \$4,%eax # have the lock, now increment the
|
||||||
xadd %eax,$tls::stackptr(%edx)
|
xadd %eax,$tls::stackptr(%edx) # stack pointer and get pointer
|
||||||
decl $tls::stacklock(%edx)
|
leal __sigbe,%ebx # new place to return to
|
||||||
leal __sigbe,%edx
|
xchgl %ebx,12(%esp) # exchange with real return value
|
||||||
xchgl %edx,8(%esp)
|
movl %ebx,(%eax) # store real return value on alt stack
|
||||||
movl %edx,(%eax)
|
decl $tls::stacklock(%edx) # remove lock
|
||||||
popl %edx
|
popl %edx # restore saved value
|
||||||
|
popl %ebx
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.global __sigbe
|
.global __sigbe
|
||||||
.stabs "_sigbe:F(0,1)",36,0,0,__sigbe
|
.stabs "_sigbe:F(0,1)",36,0,0,__sigbe
|
||||||
__sigbe:
|
__sigbe:
|
||||||
pushl %edx
|
pushl %ebx
|
||||||
pushl %eax
|
pushl %edx # return here after cygwin syscall
|
||||||
movl %fs:4,%edx
|
pushl %eax # don't clobber
|
||||||
1: movl \$1,%eax
|
1: movl %fs:4,%edx # address of bottom of tls
|
||||||
lock xchgl %eax,$tls::stacklock(%edx)
|
movl \$1,%eax # potential lock value
|
||||||
cmpl %eax,%eax
|
lock xchgl %eax,$tls::stacklock(%edx) # see if we can grab it
|
||||||
jz 2f
|
orl %eax,%eax # it will be zero
|
||||||
xorl %eax,%eax
|
jz 2f # if so
|
||||||
call _low_priority_sleep
|
xorl %eax,%eax # nope. not zero
|
||||||
jmp 1b
|
call _low_priority_sleep # sleep
|
||||||
2: movl \$-4,%eax
|
jmp 1b # and loop
|
||||||
xadd %eax,$tls::stackptr(%edx)
|
2: movl \$-4,%eax # now decrement aux stack
|
||||||
decl $tls::stacklock(%edx)
|
xadd %eax,$tls::stackptr(%edx) # and get pointer
|
||||||
xchgl %edx,-4(%eax)
|
# xorl %ebx,%ebx
|
||||||
xchgl %edx,4(%esp)
|
movl \$0x41774177,%ebx
|
||||||
|
xchgl %ebx,-4(%eax) #
|
||||||
|
xchgl %ebx,8(%esp)
|
||||||
|
decl $tls::stacklock(%edx) # release lock
|
||||||
popl %eax
|
popl %eax
|
||||||
|
popl %edx
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.global __ZN11_threadinfo3popEv
|
.global __ZN7_cygtls3popEv
|
||||||
__ZN11_threadinfo3popEv:
|
__ZN7_cygtls3popEv:
|
||||||
1: pushl %ebx
|
1: pushl %ebx
|
||||||
|
pushl %edx # FIXME: needed?
|
||||||
movl %eax,%edx
|
movl %eax,%edx
|
||||||
movl \$-4,%ebx
|
movl \$-4,%ebx
|
||||||
xadd %ebx,$tls::pstackptr(%edx)
|
xadd %ebx,$tls::pstackptr(%edx)
|
||||||
xorl %eax,%eax
|
# xorl %eax,%eax
|
||||||
|
movl 8(%esp),%eax
|
||||||
xchgl %eax,-4(%ebx)
|
xchgl %eax,-4(%ebx)
|
||||||
|
popl %edx # FIXME: needed?
|
||||||
popl %ebx
|
popl %ebx
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.global __ZN11_threadinfo4lockEv
|
.global __ZN7_cygtls4lockEv
|
||||||
__ZN11_threadinfo4lockEv:
|
__ZN7_cygtls4lockEv:
|
||||||
pushl %ebx
|
pushl %edi
|
||||||
movl %eax,%ebx
|
movl %eax,%edi
|
||||||
1: movl \$1,%eax
|
1: movl \$1,%eax
|
||||||
lock xchgl %eax,$tls::pstacklock(%ebx)
|
lock xchgl %eax,$tls::pstacklock(%edi)
|
||||||
cmpl %eax,%eax
|
orl %eax,%eax
|
||||||
jz 2f
|
jz 2f
|
||||||
xorl %eax,%eax
|
xorl %eax,%eax
|
||||||
call _low_priority_sleep
|
call _low_priority_sleep
|
||||||
jmp 1b
|
jmp 1b
|
||||||
2: xorl \$1,%eax
|
2: popl %edi
|
||||||
popl %ebx
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.global __ZN11_threadinfo6unlockEv
|
.global __ZN7_cygtls6unlockEv
|
||||||
__ZN11_threadinfo6unlockEv:
|
__ZN7_cygtls6unlockEv:
|
||||||
decl $tls::pstacklock(%eax)
|
decl $tls::pstacklock(%eax)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
.global __ZN7_cygtls6lockedEv
|
||||||
|
__ZN7_cygtls6lockedEv:
|
||||||
|
movl $tls::pstacklock(%eax),%eax
|
||||||
|
ret
|
||||||
|
|
||||||
.global _sigreturn
|
.global _sigreturn
|
||||||
.stabs "sigreturn:F(0,1)",36,0,0,_sigreturn
|
.stabs "sigreturn:F(0,1)",36,0,0,_sigreturn
|
||||||
_sigreturn:
|
_sigreturn:
|
||||||
addl \$4,%esp # Remove argument
|
addl \$4,%esp # Remove argument
|
||||||
call _set_process_mask\@4
|
call _set_process_mask\@4
|
||||||
|
|
||||||
movl %fs:4,%ebx
|
movl %fs:4,%ebx
|
||||||
|
|
||||||
cmpl \$0,$tls::sig(%ebx) # Did a signal come in?
|
# cmpl \$0,$tls::sig(%ebx) # Did a signal come in?
|
||||||
jnz 3f # Yes, if non-zero
|
# jnz 3f # Yes, if non-zero
|
||||||
|
|
||||||
1: popl %edx # saved errno
|
1: popl %edx # saved errno
|
||||||
testl %edx,%edx # Is it < 0
|
testl %edx,%edx # Is it < 0
|
||||||
@ -215,8 +228,7 @@ _sigdelayed:
|
|||||||
movl \$0,$tls::sig(%ebx) # zero the signal number as a
|
movl \$0,$tls::sig(%ebx) # zero the signal number as a
|
||||||
# flag to the signal handler thread
|
# flag to the signal handler thread
|
||||||
# that it is ok to set up sigsave
|
# that it is ok to set up sigsave
|
||||||
4: popl %ebx
|
4: ret
|
||||||
jmp *%ebx
|
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
@ -229,15 +241,26 @@ sub longjmp {
|
|||||||
.globl _longjmp
|
.globl _longjmp
|
||||||
|
|
||||||
_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
|
pushl %ebp
|
||||||
movl %esp,%ebp
|
movl %esp,%ebp
|
||||||
movl 8(%ebp),%edi
|
movl 8(%ebp),%edi
|
||||||
movl 12(%ebp),%eax
|
movl 12(%ebp),%eax
|
||||||
testl %eax,%eax
|
testl %eax,%eax
|
||||||
jne 0f
|
jne 3f
|
||||||
incl %eax
|
incl %eax
|
||||||
0:
|
|
||||||
movl %eax,0(%edi)
|
3: movl %eax,0(%edi)
|
||||||
movl 24(%edi),%ebp
|
movl 24(%edi),%ebp
|
||||||
pushfl
|
pushfl
|
||||||
popl %ebx
|
popl %ebx
|
||||||
@ -250,14 +273,12 @@ _longjmp:
|
|||||||
movw %ax,%es
|
movw %ax,%es
|
||||||
movw 40(%edi),%ax
|
movw 40(%edi),%ax
|
||||||
movw %ax,%gs
|
movw %ax,%gs
|
||||||
movl %fs:4,%eax
|
|
||||||
leal ($tls::stack)(%eax),%edx
|
|
||||||
movl %edx,($tls::stackptr)(%eax)
|
|
||||||
movl 0(%edi),%eax
|
movl 0(%edi),%eax
|
||||||
movl 4(%edi),%ebx
|
movl 4(%edi),%ebx
|
||||||
movl 8(%edi),%ecx
|
movl 8(%edi),%ecx
|
||||||
movl 12(%edi),%edx
|
|
||||||
movl 16(%edi),%esi
|
movl 16(%edi),%esi
|
||||||
|
decl $tls::stacklock(%edx)
|
||||||
|
movl 12(%edi),%edx
|
||||||
movl 20(%edi),%edi
|
movl 20(%edi),%edi
|
||||||
popfl
|
popfl
|
||||||
ret
|
ret
|
||||||
|
@ -27,7 +27,7 @@ HANDLE sync_startup;
|
|||||||
static void WINAPI
|
static void WINAPI
|
||||||
threadfunc_fe (VOID *arg)
|
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
|
static DWORD WINAPI
|
||||||
|
@ -318,7 +318,7 @@ low_priority_sleep (DWORD secs)
|
|||||||
|
|
||||||
if (!secs && wincap.has_switch_to_thread ())
|
if (!secs && wincap.has_switch_to_thread ())
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 10; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
SwitchToThread ();
|
SwitchToThread ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -58,7 +58,7 @@ class vfork_save
|
|||||||
public:
|
public:
|
||||||
int pid;
|
int pid;
|
||||||
DWORD frame[100];
|
DWORD frame[100];
|
||||||
_threadinfo tls;
|
_cygtls tls;
|
||||||
char **vfork_ebp;
|
char **vfork_ebp;
|
||||||
char **vfork_esp;
|
char **vfork_esp;
|
||||||
int ctty;
|
int ctty;
|
||||||
|
@ -30,6 +30,7 @@ details. */
|
|||||||
#include "shared_info.h"
|
#include "shared_info.h"
|
||||||
#include "cygheap.h"
|
#include "cygheap.h"
|
||||||
#include "fhandler.h"
|
#include "fhandler.h"
|
||||||
|
#include "cygmalloc.h"
|
||||||
|
|
||||||
static char NO_COPY pinfo_dummy[sizeof (_pinfo)] = {0};
|
static char NO_COPY pinfo_dummy[sizeof (_pinfo)] = {0};
|
||||||
|
|
||||||
@ -755,22 +756,14 @@ winpids::enum9x (bool winpid)
|
|||||||
return nelem;
|
return nelem;
|
||||||
}
|
}
|
||||||
|
|
||||||
NO_COPY CRITICAL_SECTION winpids::cs;
|
|
||||||
|
|
||||||
void
|
void
|
||||||
winpids::set (bool winpid)
|
winpids::set (bool winpid)
|
||||||
{
|
{
|
||||||
EnterCriticalSection (&cs);
|
__malloc_lock ();
|
||||||
npids = (this->*enum_processes) (winpid);
|
npids = (this->*enum_processes) (winpid);
|
||||||
if (pidlist)
|
if (pidlist)
|
||||||
pidlist[npids] = 0;
|
pidlist[npids] = 0;
|
||||||
LeaveCriticalSection (&cs);
|
__malloc_unlock ();
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
winpids::init ()
|
|
||||||
{
|
|
||||||
InitializeCriticalSection (&cs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD
|
DWORD
|
||||||
|
@ -179,7 +179,6 @@ class winpids
|
|||||||
DWORD enumNT (bool winpid);
|
DWORD enumNT (bool winpid);
|
||||||
DWORD enum9x (bool winpid);
|
DWORD enum9x (bool winpid);
|
||||||
void add (DWORD& nelem, bool, DWORD pid);
|
void add (DWORD& nelem, bool, DWORD pid);
|
||||||
static CRITICAL_SECTION cs;
|
|
||||||
public:
|
public:
|
||||||
DWORD npids;
|
DWORD npids;
|
||||||
inline void reset () { npids = 0; release (); }
|
inline void reset () { npids = 0; release (); }
|
||||||
@ -196,7 +195,6 @@ public:
|
|||||||
inline _pinfo *operator [] (int i) const {return (_pinfo *) pinfolist[i];}
|
inline _pinfo *operator [] (int i) const {return (_pinfo *) pinfolist[i];}
|
||||||
~winpids ();
|
~winpids ();
|
||||||
void release ();
|
void release ();
|
||||||
static void init ();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern __inline pid_t
|
extern __inline pid_t
|
||||||
|
@ -93,7 +93,7 @@ nanosleep (const struct timespec *rqtp, struct timespec *rmtp)
|
|||||||
rem = 0;
|
rem = 0;
|
||||||
if (rc == WAIT_OBJECT_0)
|
if (rc == WAIT_OBJECT_0)
|
||||||
{
|
{
|
||||||
(void) call_signal_handler_now ();
|
(void) _my_tls.call_signal_handler ();
|
||||||
set_errno (EINTR);
|
set_errno (EINTR);
|
||||||
res = -1;
|
res = -1;
|
||||||
}
|
}
|
||||||
@ -302,7 +302,7 @@ kill_pgrp (pid_t pid, siginfo_t& si)
|
|||||||
found++;
|
found++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (killself && kill_worker (myself->pid, si))
|
if (killself && !exit_state && kill_worker (myself->pid, si))
|
||||||
res = -1;
|
res = -1;
|
||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
@ -341,7 +341,7 @@ abort (void)
|
|||||||
set_signal_mask (sig_mask);
|
set_signal_mask (sig_mask);
|
||||||
|
|
||||||
raise (SIGABRT);
|
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. */
|
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
|
If sending to this process, wait for notification that a signal has
|
||||||
completed before returning. */
|
completed before returning. */
|
||||||
int __stdcall
|
int __stdcall
|
||||||
sig_send (_pinfo *p, siginfo_t& si, _threadinfo *tls)
|
sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
|
||||||
{
|
{
|
||||||
int rc = 1;
|
int rc = 1;
|
||||||
bool its_me;
|
bool its_me;
|
||||||
@ -747,7 +747,7 @@ sig_send (_pinfo *p, siginfo_t& si, _threadinfo *tls)
|
|||||||
if (!pack.si.si_uid)
|
if (!pack.si.si_uid)
|
||||||
pack.si.si_uid = myself->uid;
|
pack.si.si_uid = myself->uid;
|
||||||
pack.pid = myself->pid;
|
pack.pid = myself->pid;
|
||||||
pack.tls = (_threadinfo *) tls;
|
pack.tls = (_cygtls *) tls;
|
||||||
if (wait_for_completion)
|
if (wait_for_completion)
|
||||||
{
|
{
|
||||||
pack.wakeup = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
|
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)
|
if (wait_for_completion && si.si_signo != __SIGFLUSHFAST)
|
||||||
call_signal_handler_now ();
|
_my_tls.call_signal_handler ();
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (pack.wakeup)
|
if (pack.wakeup)
|
||||||
|
@ -54,7 +54,7 @@ struct sigpacket
|
|||||||
{
|
{
|
||||||
siginfo_t si;
|
siginfo_t si;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
class _threadinfo *tls;
|
class _cygtls *tls;
|
||||||
sigset_t *mask;
|
sigset_t *mask;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
@ -91,9 +91,8 @@ void __stdcall subproc_init ();
|
|||||||
void __stdcall sigproc_terminate ();
|
void __stdcall sigproc_terminate ();
|
||||||
bool __stdcall proc_exists (_pinfo *) __attribute__ ((regparm(1)));
|
bool __stdcall proc_exists (_pinfo *) __attribute__ ((regparm(1)));
|
||||||
bool __stdcall pid_exists (pid_t) __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)));
|
int __stdcall sig_send (_pinfo *, int) __attribute__ ((regparm (2)));
|
||||||
void __stdcall signal_fixup_after_fork ();
|
|
||||||
void __stdcall signal_fixup_after_exec ();
|
void __stdcall signal_fixup_after_exec ();
|
||||||
void __stdcall wait_for_sigthread ();
|
void __stdcall wait_for_sigthread ();
|
||||||
void __stdcall sigalloc ();
|
void __stdcall sigalloc ();
|
||||||
|
@ -69,8 +69,10 @@ int
|
|||||||
muto::acquire (DWORD ms)
|
muto::acquire (DWORD ms)
|
||||||
{
|
{
|
||||||
DWORD this_tid = GetCurrentThreadId ();
|
DWORD this_tid = GetCurrentThreadId ();
|
||||||
|
#if 0
|
||||||
if (exiting_thread)
|
if (exiting_thread)
|
||||||
return this_tid == exiting_thread;
|
return this_tid == exiting_thread;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (tid != this_tid)
|
if (tid != this_tid)
|
||||||
{
|
{
|
||||||
@ -113,8 +115,6 @@ int
|
|||||||
muto::release ()
|
muto::release ()
|
||||||
{
|
{
|
||||||
DWORD this_tid = GetCurrentThreadId ();
|
DWORD this_tid = GetCurrentThreadId ();
|
||||||
if (exiting_thread)
|
|
||||||
return this_tid == exiting_thread;
|
|
||||||
|
|
||||||
if (tid != this_tid || !visits)
|
if (tid != this_tid || !visits)
|
||||||
{
|
{
|
||||||
|
@ -461,7 +461,7 @@ readv (int fd, const struct iovec *const iov, const int iovcnt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (res >= 0 || get_errno () != EINTR || !call_signal_handler_now ())
|
if (res >= 0 || get_errno () != EINTR || !_my_tls.call_signal_handler ())
|
||||||
break;
|
break;
|
||||||
set_errno (e);
|
set_errno (e);
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ details. */
|
|||||||
#include "cygwin/version.h"
|
#include "cygwin/version.h"
|
||||||
#include "perprocess.h"
|
#include "perprocess.h"
|
||||||
#include "sigproc.h"
|
#include "sigproc.h"
|
||||||
|
#include "cygtls.h"
|
||||||
#include <sys/termios.h>
|
#include <sys/termios.h>
|
||||||
|
|
||||||
/* tcsendbreak: POSIX 7.2.2.1 */
|
/* tcsendbreak: POSIX 7.2.2.1 */
|
||||||
@ -146,7 +147,7 @@ tcsetattr (int fd, int a, const struct termios *t)
|
|||||||
e = get_errno ();
|
e = get_errno ();
|
||||||
break;
|
break;
|
||||||
case bg_signalled:
|
case bg_signalled:
|
||||||
if (call_signal_handler_now ())
|
if (_my_tls.call_signal_handler ())
|
||||||
continue;
|
continue;
|
||||||
res = -1;
|
res = -1;
|
||||||
/* fall through intentionally */
|
/* fall through intentionally */
|
||||||
|
@ -348,7 +348,7 @@ private:
|
|||||||
|
|
||||||
#define WAIT_CANCELED (WAIT_OBJECT_0 + 1)
|
#define WAIT_CANCELED (WAIT_OBJECT_0 + 1)
|
||||||
|
|
||||||
class _threadinfo;
|
class _cygtls;
|
||||||
class pthread: public verifyable_object
|
class pthread: public verifyable_object
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -360,7 +360,7 @@ public:
|
|||||||
bool valid;
|
bool valid;
|
||||||
bool suspended;
|
bool suspended;
|
||||||
int cancelstate, canceltype;
|
int cancelstate, canceltype;
|
||||||
_threadinfo *cygtls;
|
_cygtls *cygtls;
|
||||||
HANDLE cancel_event;
|
HANDLE cancel_event;
|
||||||
pthread_t joiner;
|
pthread_t joiner;
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ details. */
|
|||||||
#include "sigproc.h"
|
#include "sigproc.h"
|
||||||
#include "perthread.h"
|
#include "perthread.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
|
#include "cygtls.h"
|
||||||
|
|
||||||
/* This is called _wait and not wait because the real wait is defined
|
/* This is called _wait and not wait because the real wait is defined
|
||||||
in libc/syscalls/syswait.c. It calls us. */
|
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)
|
if (w->status == -1)
|
||||||
{
|
{
|
||||||
set_sig_errno (EINTR);
|
set_sig_errno (EINTR);
|
||||||
call_signal_handler_now ();
|
_my_tls.call_signal_handler ();
|
||||||
sawsig = true;
|
sawsig = true;
|
||||||
res = -1;
|
res = -1;
|
||||||
}
|
}
|
||||||
@ -114,7 +115,7 @@ wait4 (int intpid, int *status, int options, struct rusage *r)
|
|||||||
*status = w->status;
|
*status = w->status;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (!sawsig || !call_signal_handler_now ())
|
if (!sawsig || !_my_tls.call_signal_handler ())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,7 +239,7 @@ extern "C" int try_to_debug (bool waitloop = 1);
|
|||||||
|
|
||||||
void set_file_api_mode (codepage_type);
|
void set_file_api_mode (codepage_type);
|
||||||
|
|
||||||
extern int cygwin_finished_initializing;
|
extern bool cygwin_finished_initializing;
|
||||||
|
|
||||||
/**************************** Miscellaneous ******************************/
|
/**************************** Miscellaneous ******************************/
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user