diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 99a6e5483..f5760e631 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,18 @@ +2004-12-22 Christopher Faylor + + * cygheap.cc (cygheap_setup_for_child): Add api_fatal to catch failing + MapViewOfFileEx. + * cygthread.cc (cygthread::stub): Previous change to make diagnostic + output more informative was really a bust. Try again. Capture previous + name in a new field in cygthread for diagnostic purposes. + (cygthread::cygthread): Ditto. + (cygthread::release): Add an argument to control whether h should be cleared + or not. + (cygthread::terminate_thread): Use 'inuse' for tests rather than 'h'. + (cygthread): Add some diagnostic fields. + (cygthread::release): Add an argument. + * pinfo.cc (proc_waiter): Accommodate change to cygthread::release. + 2004-12-22 Christopher Faylor * cygthread.cc (cygthread::stub): Make diagnostic output more informative. diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc index 6a6aa19a5..14cdd8d84 100644 --- a/winsup/cygwin/cygheap.cc +++ b/winsup/cygwin/cygheap.cc @@ -111,6 +111,8 @@ cygheap_setup_for_child (child_info *ci, bool dup_later) if (!ci->cygheap_h) api_fatal ("Couldn't create heap for child, size %d, %E", size); newcygheap = MapViewOfFileEx (ci->cygheap_h, MVMAP_OPTIONS, 0, 0, 0, NULL); + if (!newcygheap) + api_fatal ("couldn't map space for new cygheap, %E"); ProtectHandle1INH (ci->cygheap_h, passed_cygheap_h); if (!dup_later) dup_now (newcygheap, ci, n); diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc index 55f745a8b..949f4716c 100644 --- a/winsup/cygwin/cygthread.cc +++ b/winsup/cygwin/cygthread.cc @@ -54,9 +54,12 @@ cygthread::stub (VOID *arg) while (1) { - const char *name = info->__name; - if (!name) - system_printf ("erroneous thread activation, name is non-NULL '%s'", name); + if (!info->__name) +#ifdef DEBUGGING + system_printf ("erroneous thread activation, name is NULL prev thread name = '%s'", info->__oldname); +#else + system_printf ("erroneous thread activation, name is NULL"); +#endif else { if (!info->func || exiting) @@ -68,6 +71,7 @@ cygthread::stub (VOID *arg) #ifdef DEBUGGING info->func = NULL; // catch erroneous activation + info->__oldname = info->__name; #endif info->__name = NULL; if (info->inuse) @@ -159,11 +163,16 @@ cygthread::cygthread (LPTHREAD_START_ROUTINE start, LPVOID param, else { stack_ptr = NULL; +#ifdef DEBUGGING + if (__oldname) + system_printf ("__oldname %s, terminated %d", __oldname, terminated); +#endif h = CreateThread (&sec_none_nih, 0, is_freerange ? simplestub : stub, this, 0, &id); if (!h) api_fatal ("thread handle not set - %p<%p>, %E", h, id); thread_printf ("created thread %p", h); + terminated = false; } } @@ -215,9 +224,11 @@ cygthread::exit_thread () } void -cygthread::release () +cygthread::release (bool nuke_h) { - h = NULL; + if (nuke_h) + h = NULL; + __oldname = __name; __name = NULL; stack_ptr = NULL; (void) InterlockedExchange (&inuse, 0); /* No longer in use */ @@ -227,7 +238,7 @@ cygthread::release () void cygthread::terminate_thread () { - /* FIXME: The if (!h) stuff below should be handled better. The + /* FIXME: The if (!inuse) stuff below should be handled better. The problem is that terminate_thread could be called while a thread is terminating and either the thread could be handling its own release or, if this is being called during exit, some other @@ -239,19 +250,19 @@ cygthread::terminate_thread () ResetEvent (*this); ResetEvent (thread_sync); } - if (!h) + if (!inuse) return; (void) TerminateThread (h, 0); (void) WaitForSingleObject (h, INFINITE); - if (!h) + if (!inuse) return; CloseHandle (h); - while (h && !stack_ptr) + while (inuse && !stack_ptr) low_priority_sleep (0); - if (!h) + if (!inuse) return; MEMORY_BASIC_INFORMATION m; @@ -264,10 +275,17 @@ cygthread::terminate_thread () debug_printf ("VirtualFree of allocation base %p<%p> failed, %E", stack_ptr, m.AllocationBase); + if (!inuse) + /* nothing */; if (is_freerange) free (this); else - release (); + { +#ifdef DEBUGGING + terminated = true; +#endif + release (true); + } } /* Detach the cygthread from the current thread. Note that the diff --git a/winsup/cygwin/cygthread.h b/winsup/cygwin/cygthread.h index ae7ff9292..265e51ceb 100644 --- a/winsup/cygwin/cygthread.h +++ b/winsup/cygwin/cygthread.h @@ -18,6 +18,10 @@ class cygthread HANDLE thread_sync; void *stack_ptr; const char *__name; +#ifdef DEBUGGING + const char *__oldname; + bool terminated; +#endif LPTHREAD_START_ROUTINE func; VOID *arg; bool is_freerange; @@ -28,7 +32,7 @@ class cygthread static DWORD WINAPI simplestub (VOID *); static DWORD main_thread_id; static const char * name (DWORD = 0); - void release (); + void release (bool); cygthread (LPTHREAD_START_ROUTINE, LPVOID, const char *); cygthread () {}; static void init (); diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index 508ed5cb6..af0b893b0 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -764,7 +764,7 @@ proc_waiter (void *arg) sigproc_printf ("exiting wait thread for pid %d", pid); vchild.wait_thread = NULL; - _my_tls._ctinfo->release (); /* return the cygthread to the cygthread pool */ + _my_tls._ctinfo->release (false); /* return the cygthread to the cygthread pool */ return 0; }