diff options
author | Christopher Faylor <me@cgf.cx> | 2002-08-05 16:15:46 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2002-08-05 16:15:46 +0000 |
commit | 8d0bc156efc1246ce894f7d844a41384383c0c7f (patch) | |
tree | e969d18c7f7efadc6a69b66d32a6e0483c145c13 /winsup | |
parent | 9f37f36de673fd5b0a8ca36b8a2ffd41a6d346ec (diff) | |
download | newlib-8d0bc156efc1246ce894f7d844a41384383c0c7f.zip newlib-8d0bc156efc1246ce894f7d844a41384383c0c7f.tar.gz newlib-8d0bc156efc1246ce894f7d844a41384383c0c7f.tar.bz2 |
* 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.
Diffstat (limited to 'winsup')
-rw-r--r-- | winsup/cygwin/ChangeLog | 6 | ||||
-rw-r--r-- | winsup/cygwin/cygthread.cc | 31 |
2 files changed, 30 insertions, 7 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index c042dab..566389d 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -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. diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc index a4f3247..883b43f 100644 --- a/winsup/cygwin/cygthread.cc +++ b/winsup/cygwin/cygthread.cc @@ -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); } } |