From aea1f301fcc9037a222ccf7c2f0f247cdeb2d06e Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Sun, 29 Sep 2002 02:19:35 +0000 Subject: * cygthread.h (cygthread::terminate): Declare new function. (cygthread::initialized): Change to 'int'. * cygthread.cc (cygthread::stub): Exit thread if initialized < 0. (cygthread::new): Ditto. (cygthread::runner): Ditto. Set initialized using xor to preserve sign. (cygthread::terminate): New function. * dcrt0.cc (do_exit): Call cygthread::terminate. --- winsup/cygwin/cygthread.cc | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) (limited to 'winsup/cygwin/cygthread.cc') diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc index b81c4c16f..b2a62247b 100644 --- a/winsup/cygwin/cygthread.cc +++ b/winsup/cygwin/cygthread.cc @@ -19,7 +19,7 @@ static cygthread NO_COPY threads[6]; #define NTHREADS (sizeof (threads) / sizeof (threads[0])) DWORD NO_COPY cygthread::main_thread_id; -bool NO_COPY cygthread::initialized; +int NO_COPY cygthread::initialized; /* Initial stub called by cygthread constructor. Performs initial per-thread initialization and loops waiting for new thread functions @@ -68,7 +68,10 @@ cygthread::stub (VOID *arg) #endif SetEvent (info->ev); info->__name = NULL; - SuspendThread (info->h); + if (initialized < 0) + ExitThread (0); + else + SuspendThread (info->h); } } @@ -78,9 +81,14 @@ DWORD WINAPI cygthread::runner (VOID *arg) { for (unsigned i = 0; i < NTHREADS; i++) - threads[i].h = CreateThread (&sec_none_nih, 0, cygthread::stub, &threads[i], - CREATE_SUSPENDED, &threads[i].avail); - cygthread::initialized = true; + if (!initialized) + threads[i].h = CreateThread (&sec_none_nih, 0, cygthread::stub, + &threads[i], CREATE_SUSPENDED, + &threads[i].avail); + else + return 0; + + initialized ^= 1; return 0; } @@ -127,7 +135,10 @@ new (size_t) for (;;) { - bool was_initialized = initialized; + int was_initialized = initialized; + if (was_initialized < 0) + ExitThread (0); + /* Search the threads array for an empty slot to use */ for (info = threads + NTHREADS - 1; info >= threads; info--) if ((id = (DWORD) InterlockedExchange ((LPLONG) &info->avail, 0))) @@ -140,6 +151,9 @@ new (size_t) return info; } + if (was_initialized < 0) + ExitThread (0); + if (!was_initialized) Sleep (0); /* thread_runner is not finished yet. */ else @@ -259,3 +273,12 @@ cygthread::detach () } } } + +void +cygthread::terminate () +{ + initialized = -1; + for (cygthread *info = threads + NTHREADS - 1; info >= threads; info--) + if (!(DWORD) InterlockedExchange ((LPLONG) &info->avail, 0) && info->id) + SetEvent (info->ev); +} -- cgit v1.2.3