From 1524ae42cf8595fd9a31084382ade0ff17172626 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Tue, 6 Aug 2002 05:08:55 +0000 Subject: * cygthread.cc (cygthread::stub): Accept flag to pass info structure to thread function. (cygthread::operator new): Add defense debugging output. (cygthread::cygthread): Add debugging output. Set name after thread has been awakened to avoid a race. (cygthread::exit_thread): Use handle operator rather than using ev directly. (cygthread::exit_thread): Reorganize to provide debugging. Set __name to NULL. * cygthread.h (cygself): Define. * fhandler_tty.cc (fhandler_tty_master::init): Use cygself as argument so that invoked thread can access its own info. (process_output): Derive cygthread info of thread from thread argument. * sigproc.cc (sigproc_init): Use cygself as argument so that invoked thread can access its own info. (wait_sig): Derive cygthread info of thread from thread argument. --- winsup/cygwin/ChangeLog | 19 +++++++++++++++++++ winsup/cygwin/cygthread.cc | 34 ++++++++++++++++++++++++++-------- winsup/cygwin/cygthread.h | 2 ++ winsup/cygwin/fhandler_tty.cc | 6 +++--- winsup/cygwin/sigproc.cc | 6 +++--- 5 files changed, 53 insertions(+), 14 deletions(-) (limited to 'winsup') diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 4d56d1731..f25d06a2d 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,22 @@ +2002-08-06 Christopher Faylor + + * cygthread.cc (cygthread::stub): Accept flag to pass info structure to + thread function. + (cygthread::operator new): Add defense debugging output. + (cygthread::cygthread): Add debugging output. Set name after thread + has been awakened to avoid a race. + (cygthread::exit_thread): Use handle operator rather than using ev + directly. + (cygthread::exit_thread): Reorganize to provide debugging. Set __name + to NULL. + * cygthread.h (cygself): Define. + * fhandler_tty.cc (fhandler_tty_master::init): Use cygself as argument + so that invoked thread can access its own info. + (process_output): Derive cygthread info of thread from thread argument. + * sigproc.cc (sigproc_init): Use cygself as argument so that invoked + thread can access its own info. + (wait_sig): Derive cygthread info of thread from thread argument. + 2002-08-06 Conrad Scott * debug.h (handle_list::allocated): Remove field. diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc index 883b43f7e..00eeb25d0 100644 --- a/winsup/cygwin/cygthread.cc +++ b/winsup/cygwin/cygthread.cc @@ -41,10 +41,13 @@ cygthread::stub (VOID *arg) if (!info->func) ExitThread (0); - /* Cygwin threads should not call ExitThread */ - info->func (info->arg); + /* Cygwin threads should not call ExitThread directly */ + info->func (info->arg == cygself ? info : info->arg); + /* ...so the above should always return */ - debug_printf ("returned from function %p", info->func); +#ifdef DEBUGGING + info->func = NULL; // catch erroneous activation +#endif SetEvent (info->ev); info->__name = NULL; SuspendThread (info->h); @@ -100,6 +103,10 @@ new (size_t) if ((id = (DWORD) InterlockedExchange ((LPLONG) &info->avail, 0))) { info->id = id; +#ifdef DEBUGGING + if (info->__name) + api_fatal ("name not NULL? id %p, i %d", id, info - threads); +#endif return info; } @@ -109,10 +116,18 @@ new (size_t) } cygthread::cygthread (LPTHREAD_START_ROUTINE start, LPVOID param, - const char *name): __name (name), func (start), arg (param) + const char *name): func (start), arg (param) { +#ifdef DEBUGGGING + if (!__name) + api_fatal ("name should never be NULL"); +#endif + thread_printf ("name %s, id %p", name, id); while (ResumeThread (h) == 0) Sleep (0); + __name = name; /* Need to set after thread has woken up to + ensure that it won't be cleared by exiting + thread. */ } /* Return the symbolic name of the current thread for debugging. @@ -157,7 +172,7 @@ HANDLE () void cygthread::exit_thread () { - SetEvent (ev); + SetEvent (*this); ExitThread (0); } @@ -168,20 +183,23 @@ cygthread::exit_thread () void cygthread::detach () { - if (!avail) + if (avail) + system_printf ("called detach on available thread %d?", avail); + else { DWORD avail = id; /* Checking for __name here is just a minor optimization to avoid an OS call. */ if (!__name) - debug_printf ("thread routine returned. No need to wait."); + thread_printf ("thread id %p returned. No need to wait.", id); else { DWORD res = WaitForSingleObject (*this, INFINITE); - debug_printf ("WFSO returns %d", res); + thread_printf ("WFSO returns %d, id %p", res, id); } ResetEvent (*this); id = 0; + __name = NULL; /* Mark the thread as available by setting avail to non-zero */ (void) InterlockedExchange ((LPLONG) &this->avail, avail); } diff --git a/winsup/cygwin/cygthread.h b/winsup/cygwin/cygthread.h index b4f6cbe2f..7f5a59455 100644 --- a/winsup/cygwin/cygthread.h +++ b/winsup/cygwin/cygthread.h @@ -29,3 +29,5 @@ class cygthread void * operator new (size_t); void exit_thread (); }; + +#define cygself NULL diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index a7b7d814d..acc32f883 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -69,7 +69,7 @@ fhandler_tty_master::init (int ntty) h = new cygthread (process_ioctl, NULL, "ttyioctl"); SetThreadPriority (*h, THREAD_PRIORITY_HIGHEST); - output_thread = new cygthread (process_output, NULL, "ttyout"); + output_thread = new cygthread (process_output, cygself, "ttyout"); SetThreadPriority (*output_thread, THREAD_PRIORITY_HIGHEST); return 0; @@ -369,7 +369,7 @@ out: } static DWORD WINAPI -process_output (void *) +process_output (void *self) { char buf[OUT_BUFFER_SIZE*2]; @@ -380,7 +380,7 @@ process_output (void *) { if (n < 0) termios_printf ("ReadFile %E"); - cygthread *t = tty_master->output_thread; + cygthread *t = (cygthread *) self; tty_master->output_thread = NULL; t->exit_thread (); } diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 49947840e..96ba45a5b 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -571,7 +571,7 @@ sigproc_init () signal_arrived = CreateEvent(&sec_none_nih, TRUE, FALSE, NULL); ProtectHandle (signal_arrived); - hwait_sig = new cygthread (wait_sig, NULL, "sig"); + hwait_sig = new cygthread (wait_sig, cygself, "sig"); /* sync_proc_subproc is used by proc_subproc. It serialises * access to the children and zombie arrays. @@ -1030,10 +1030,10 @@ stopped_or_terminated (waitq *parent_w, _pinfo *child) * has been handled, as per POSIX. */ static DWORD WINAPI -wait_sig (VOID *) +wait_sig (VOID *self) { /* Initialization */ - (void) SetThreadPriority (*hwait_sig, WAIT_SIG_PRIORITY); + (void) SetThreadPriority (*((cygthread *) self), WAIT_SIG_PRIORITY); /* sigcatch_nosync - semaphore incremented by sig_dispatch_pending and * by foreign processes to force an examination of -- cgit v1.2.3