]> sourceware.org Git - newlib-cygwin.git/commitdiff
* cygthread.cc (cygthread::stub): Change event creation to manual reset. Set
authorChristopher Faylor <me@cgf.cx>
Mon, 5 Aug 2002 16:15:46 +0000 (16:15 +0000)
committerChristopher Faylor <me@cgf.cx>
Mon, 5 Aug 2002 16:15:46 +0000 (16:15 +0000)
__name after calling SetEvent to prevent races.
(cygthread::detach): Always reset event here to prevent races.

winsup/cygwin/ChangeLog
winsup/cygwin/cygthread.cc

index c042dab342095fb52b30099660ce102dc513a558..566389dfb7ac2aa4156f0f33fc35c221b69d0b6a 100644 (file)
@@ -1,3 +1,9 @@
+2002-08-05  Christopher Faylor  <cgf@redhat.com>
+
+       * cygthread.cc (cygthread::stub): Change event creation to manual
+       reset.  Set __name after calling SetEvent to prevent races.
+       (cygthread::detach): Always reset event here to prevent races.
+
 2002-08-03  Conrad Scott  <conrad.scott@dsl.pipex.com>
 
        * debug.h (WaitForMultipleObjects): Correct typo.
index a4f32472de10dd202618b5fc08cbe4bd86427d2f..883b43f7e758c1cc53c70938d52c339fc805aa9d 100644 (file)
@@ -7,10 +7,10 @@ Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
 details. */
 
 #include "winsup.h"
+#include <windows.h>
 #include "exceptions.h"
 #include "security.h"
 #include "cygthread.h"
-#include <windows.h>
 
 #undef CloseHandle
 
@@ -21,8 +21,9 @@ static HANDLE NO_COPY hthreads[NTHREADS];
 
 DWORD NO_COPY cygthread::main_thread_id;
 
-/* Initial stub called by makethread. Performs initial per-thread
-   initialization.  */
+/* Initial stub called by cygthread constructor. Performs initial
+   per-thread initialization and loops waiting for new thread functions
+   to execute.  */
 DWORD WINAPI
 cygthread::stub (VOID *arg)
 {
@@ -34,7 +35,7 @@ cygthread::stub (VOID *arg)
   init_exceptions (&except_entry);
 
   cygthread *info = (cygthread *) arg;
-  info->ev = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
+  info->ev = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
   while (1)
     {
       if (!info->func)
@@ -43,12 +44,15 @@ cygthread::stub (VOID *arg)
       /* Cygwin threads should not call ExitThread */
       info->func (info->arg);
 
-      info->__name = NULL;
+      debug_printf ("returned from function %p", info->func);
       SetEvent (info->ev);
+      info->__name = NULL;
       SuspendThread (info->h);
     }
 }
 
+/* This function runs in a secondary thread and starts up a bunch of
+   other suspended threads for use in the cygthread pool. */
 DWORD WINAPI
 cygthread::runner (VOID *arg)
 {
@@ -59,6 +63,7 @@ cygthread::runner (VOID *arg)
   return 0;
 }
 
+/* Start things going.  Called from dll_crt0_1. */
 void
 cygthread::init ()
 {
@@ -86,7 +91,7 @@ void * cygthread::operator
 new (size_t)
 {
   DWORD id;
-  cygthread *info; /* Various information needed by the newly created thread */
+  cygthread *info;
 
   for (;;)
     {
@@ -147,6 +152,8 @@ HANDLE ()
   return ev;
 }
 
+/* Should only be called when the process is exiting since it
+   leaves an open thread slot. */
 void
 cygthread::exit_thread ()
 {
@@ -154,18 +161,28 @@ cygthread::exit_thread ()
   ExitThread (0);
 }
 
+/* Detach the cygthread from the current thread.  Note that the
+   theory is that cygthread's are only associated with one thread.
+   So, there should be no problems with multiple threads doing waits
+   on the one cygthread. */
 void
 cygthread::detach ()
 {
   if (!avail)
     {
       DWORD avail = id;
-      if (__name)
+      /* 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.");
+      else
        {
          DWORD res = WaitForSingleObject (*this, INFINITE);
          debug_printf ("WFSO returns %d", res);
        }
+      ResetEvent (*this);
       id = 0;
+      /* Mark the thread as available by setting avail to non-zero */
       (void) InterlockedExchange ((LPLONG) &this->avail, avail);
     }
 }
This page took 0.040215 seconds and 5 git commands to generate.