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

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2002-08-06 09:08:55 +0400
committerChristopher Faylor <me@cgf.cx>2002-08-06 09:08:55 +0400
commit1524ae42cf8595fd9a31084382ade0ff17172626 (patch)
treeede26f12347598e90e3f481198a5f35b6fe0c647 /winsup/cygwin/cygthread.cc
parentffebb4fe0c3e1c3ca5ab14ec7737da054e2dc096 (diff)
* 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.
Diffstat (limited to 'winsup/cygwin/cygthread.cc')
-rw-r--r--winsup/cygwin/cygthread.cc34
1 files changed, 26 insertions, 8 deletions
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);
}