* 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.
This commit is contained in:
Christopher Faylor 2002-08-06 05:08:55 +00:00
parent ffebb4fe0c
commit 1524ae42cf
5 changed files with 53 additions and 14 deletions

View File

@ -1,3 +1,22 @@
2002-08-06 Christopher Faylor <cgf@redhat.com>
* 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 <conrad.scott@dsl.pipex.com>
* debug.h (handle_list::allocated): Remove field.

View File

@ -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);
}

View File

@ -29,3 +29,5 @@ class cygthread
void * operator new (size_t);
void exit_thread ();
};
#define cygself NULL

View File

@ -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 ();
}

View File

@ -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