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-10-23 00:16:31 +0400
committerChristopher Faylor <me@cgf.cx>2002-10-23 00:16:31 +0400
commitd525130f0403aff59eca72693d9a15648741e88e (patch)
tree16549d8075aa4ee8df6f5f6c64717b4218072640
parent329b9ead3ea5a48d452ce48538a4584835c70555 (diff)
* cygthread.cc (cygthread::exiting): New variable.
(cygthread::initialized): Delete. (cygthread::stub): Use exiting variable to determine when to exit. (cygthread::runner): Delete. (cygthread_protect): New variable. (cygthread::init): Don't start runner thread. Initialize muto for list protection. (cygthread::freerange): Return pointer to cygthread. (cygthread::operator new): Change logic to start threads on an as-needed basis. (cygthread::detach): Don't zero id. (cygthread::terminate): Don't kill any executing threads. Just set exiting flag. * cygthread.h (cygthread): Reflect above changes. * dcrt0.cc (dll_crt0_1): Move cygthread initialization later. * fork.cc (fork_child): Do fdtab fixup after dll fixup or (apparently) winsock may allocate memory in dll load address.
-rw-r--r--winsup/cygwin/ChangeLog21
-rw-r--r--winsup/cygwin/cygthread.cc124
-rw-r--r--winsup/cygwin/cygthread.h6
-rw-r--r--winsup/cygwin/dcrt0.cc9
-rw-r--r--winsup/cygwin/fork.cc10
5 files changed, 65 insertions, 105 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index ae748e04c..dd05d4a8b 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,24 @@
+2002-10-22 Christopher Faylor <cgf@redhat.com>
+
+ * cygthread.cc (cygthread::exiting): New variable.
+ (cygthread::initialized): Delete.
+ (cygthread::stub): Use exiting variable to determine when to exit.
+ (cygthread::runner): Delete.
+ (cygthread_protect): New variable.
+ (cygthread::init): Don't start runner thread. Initialize muto for list
+ protection.
+ (cygthread::freerange): Return pointer to cygthread.
+ (cygthread::operator new): Change logic to start threads on an
+ as-needed basis.
+ (cygthread::detach): Don't zero id.
+ (cygthread::terminate): Don't kill any executing threads. Just set
+ exiting flag.
+ * cygthread.h (cygthread): Reflect above changes.
+ * dcrt0.cc (dll_crt0_1): Move cygthread initialization later.
+
+ * fork.cc (fork_child): Do fdtab fixup after dll fixup or (apparently)
+ winsock may allocate memory in dll load address.
+
2002-10-22 Pierre Humblet <pierre.humblet@ieee.org>
* sec_helper.cc (cygsid::get_id): If the sid matches a sid stored in
diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc
index 7143d70bb..70225f0cf 100644
--- a/winsup/cygwin/cygthread.cc
+++ b/winsup/cygwin/cygthread.cc
@@ -12,6 +12,7 @@ details. */
#include "exceptions.h"
#include "security.h"
#include "cygthread.h"
+#include "sync.h"
#undef CloseHandle
@@ -19,7 +20,7 @@ static cygthread NO_COPY threads[9];
#define NTHREADS (sizeof (threads) / sizeof (threads[0]))
DWORD NO_COPY cygthread::main_thread_id;
-int NO_COPY cygthread::initialized;
+bool NO_COPY cygthread::exiting;
/* Initial stub called by cygthread constructor. Performs initial
per-thread initialization and loops waiting for new thread functions
@@ -48,7 +49,7 @@ cygthread::stub (VOID *arg)
system_printf ("erroneous thread activation");
else
{
- if (!info->func || initialized < 0)
+ if (!info->func || exiting)
ExitThread (0);
/* Cygwin threads should not call ExitThread directly */
@@ -89,33 +90,12 @@ cygthread::simplestub (VOID *arg)
ExitThread (0);
}
-/* 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)
-{
- for (unsigned i = 0; i < NTHREADS; i++)
- if (!initialized)
- threads[i].h = CreateThread (&sec_none_nih, 0, cygthread::stub,
- &threads[i], CREATE_SUSPENDED,
- &threads[i].avail);
- else
- ExitThread (0);
-
- initialized ^= 1;
- ExitThread (0);
-}
-
-HANDLE NO_COPY runner_handle;
-DWORD NO_COPY runner_tid;
+static NO_COPY muto *cygthread_protect;
/* Start things going. Called from dll_crt0_1. */
void
cygthread::init ()
{
- runner_handle = CreateThread (&sec_none_nih, 0, cygthread::runner, NULL, 0,
- &runner_tid);
- if (!runner_handle)
- api_fatal ("can't start thread_runner, %E");
+ new_muto (cygthread_protect);
main_thread_id = GetCurrentThreadId ();
}
@@ -131,7 +111,7 @@ cygthread::is ()
return 0;
}
-void *
+cygthread *
cygthread::freerange ()
{
cygthread *self = (cygthread *) calloc (1, sizeof (*self));
@@ -148,39 +128,36 @@ new (size_t)
DWORD id;
cygthread *info;
- for (;;)
- {
- 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)))
- {
- info->id = id;
+ cygthread_protect->acquire ();
+
+ /* Search the threads array for an empty slot to use */
+ for (info = threads; info < threads + NTHREADS; info++)
+ if ((id = (DWORD) InterlockedExchange ((LPLONG) &info->avail, 0)))
+ {
#ifdef DEBUGGING
- if (info->__name)
- api_fatal ("name not NULL? id %p, i %d", id, info - threads);
+ if (info->__name)
+ api_fatal ("name not NULL? id %p, i %d", id, info - threads);
#endif
- return info;
- }
-
- if (was_initialized < 0)
- ExitThread (0);
+ goto out;
+ }
+ else if (!info->id)
+ {
+ info->h = CreateThread (&sec_none_nih, 0, cygthread::stub, info,
+ CREATE_SUSPENDED, &info->id);
+ goto out;
+ }
- if (!was_initialized)
- Sleep (0); /* thread_runner is not finished yet. */
- else
- {
#ifdef DEBUGGING
- char buf[1024];
- if (!GetEnvironmentVariable ("CYGWIN_NOFREERANGE_NOCHECK", buf, sizeof (buf)))
- api_fatal ("Overflowed cygwin thread pool");
+ char buf[1024];
+ if (!GetEnvironmentVariable ("CYGWIN_NOFREERANGE_NOCHECK", buf, sizeof (buf)))
+ api_fatal ("Overflowed cygwin thread pool");
#endif
- return freerange ();
- }
- }
+
+ info = freerange (); /* exhausted thread pool */
+
+out:
+ cygthread_protect->release ();
+ return info;
}
cygthread::cygthread (LPTHREAD_START_ROUTINE start, LPVOID param,
@@ -200,9 +177,7 @@ cygthread::cygthread (LPTHREAD_START_ROUTINE start, LPVOID param,
Sleep (0);
}
#endif
- __name = name; /* Need to set after thread has woken up to
- ensure that it won't be cleared by exiting
- thread. */
+ __name = name;
if (!thread_sync)
ResumeThread (h);
else
@@ -278,7 +253,6 @@ cygthread::detach ()
}
else
{
- id = 0;
ResetEvent (*this);
/* Mark the thread as available by setting avail to non-zero */
(void) InterlockedExchange ((LPLONG) &this->avail, avail);
@@ -289,37 +263,5 @@ cygthread::detach ()
void
cygthread::terminate ()
{
- /* Wow. All of this seems to be necessary or (on Windows 9x at least) the
- process will sometimes deadlock if there are suspended threads. I assume
- that something funky is happening like a suspended thread being created
- while the process is exiting or something. In particular, it seems like
- the WaitForSingleObjects are necessary since it appears that the
- TerminateThread call may happen asynchronously, i.e., when TerminateThread
- returns, the thread may not yet have terminated. */
- if (runner_handle && initialized >= 0)
- {
- /* Don't care about detaching (or attaching) threads now */
- if (cygwin_hmodule && !DisableThreadLibraryCalls (cygwin_hmodule))
- system_printf ("DisableThreadLibraryCalls (%p) failed, %E",
- cygwin_hmodule);
- initialized = -1;
- (void) TerminateThread (runner_handle, 0);
- (void) WaitForSingleObject (runner_handle, INFINITE);
- (void) CloseHandle (runner_handle);
- HANDLE hthreads[NTHREADS];
- int n = 0;
- for (unsigned i = 0; i < NTHREADS; i++)
- if (threads[i].h)
- {
- hthreads[n] = threads[i].h;
- threads[i].h = NULL;
- TerminateThread (hthreads[n++], 0);
- }
- if (n)
- {
- (void) WaitForMultipleObjects (n, hthreads, TRUE, INFINITE);
- while (--n >= 0)
- CloseHandle (hthreads[n]);
- }
- }
+ exiting = 1;
}
diff --git a/winsup/cygwin/cygthread.h b/winsup/cygwin/cygthread.h
index ded205f30..774c656da 100644
--- a/winsup/cygwin/cygthread.h
+++ b/winsup/cygwin/cygthread.h
@@ -18,9 +18,7 @@ class cygthread
VOID *arg;
bool is_freerange;
static DWORD main_thread_id;
- static int initialized;
- static DWORD WINAPI runner (VOID *);
- static DWORD WINAPI free_runner (VOID *);
+ static bool exiting;
static DWORD WINAPI stub (VOID *);
static DWORD WINAPI simplestub (VOID *);
public:
@@ -32,7 +30,7 @@ class cygthread
operator HANDLE ();
static bool is ();
void * operator new (size_t);
- static void * freerange ();
+ static cygthread *freerange ();
void exit_thread ();
static void terminate ();
bool SetThreadPriority (int nPriority) {return ::SetThreadPriority (h, nPriority);}
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index 89c9a4456..22899e452 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -573,10 +573,7 @@ dll_crt0_1 ()
char **envp = NULL;
if (!child_proc_info)
- {
- cygthread::init ();
- memory_init ();
- }
+ memory_init ();
else
{
bool close_ppid_handle = false;
@@ -587,7 +584,6 @@ dll_crt0_1 ()
alloc_stack (fork_info);
cygheap_fixup_in_child (0);
memory_init ();
- cygthread::init ();
set_myself (mypid);
close_ppid_handle = !!child_proc_info->pppid_handle;
break;
@@ -600,7 +596,6 @@ dll_crt0_1 ()
hexec_proc = spawn_info->hexec_proc;
around:
HANDLE h;
- cygthread::init ();
cygheap_fixup_in_child (1);
memory_init ();
if (!spawn_info->moreinfo->myself_pinfo ||
@@ -621,7 +616,6 @@ dll_crt0_1 ()
old_title = strcpy (title_buf, spawn_info->moreinfo->old_title);
cfree (spawn_info->moreinfo->old_title);
}
- // cygthread::init ();
break;
}
if (close_hexec_proc)
@@ -632,6 +626,7 @@ dll_crt0_1 ()
ProtectHandle (hMainProc);
ProtectHandle (hMainThread);
+ cygthread::init ();
/* Initialize debug muto, if DLL is built with --enable-debugging.
Need to do this before any helper threads start. */
diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc
index 165c794ca..a547c7721 100644
--- a/winsup/cygwin/fork.cc
+++ b/winsup/cygwin/fork.cc
@@ -281,8 +281,6 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
if (fixup_mmaps_after_fork (hParent))
api_fatal ("recreate_mmaps_after_fork_failed");
- cygheap->fdtab.fixup_after_fork (hParent);
- ProtectHandleINH (hParent);
MALLOC_CHECK;
@@ -291,10 +289,16 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
that we're done, and wait for the parent to fill in the.
loaded dlls' data/bss. */
if (!load_dlls)
- sync_with_parent ("performed fork fixup.", FALSE);
+ {
+ cygheap->fdtab.fixup_after_fork (hParent);
+ ProtectHandleINH (hParent);
+ sync_with_parent ("performed fork fixup.", FALSE);
+ }
else
{
dlls.load_after_fork (hParent, first_dll);
+ cygheap->fdtab.fixup_after_fork (hParent);
+ ProtectHandleINH (hParent);
sync_with_parent ("loaded dlls", TRUE);
}