* 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.
This commit is contained in:
		| @@ -1,3 +1,18 @@ | |||||||
|  | 2004-12-22  Christopher Faylor  <cgf@timesys.com> | ||||||
|  |  | ||||||
|  | 	* 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  <cgf@timesys.com> | 2004-12-22  Christopher Faylor  <cgf@timesys.com> | ||||||
|  |  | ||||||
| 	* cygthread.cc (cygthread::stub): Make diagnostic output more informative. | 	* cygthread.cc (cygthread::stub): Make diagnostic output more informative. | ||||||
|   | |||||||
| @@ -111,6 +111,8 @@ cygheap_setup_for_child (child_info *ci, bool dup_later) | |||||||
|   if (!ci->cygheap_h) |   if (!ci->cygheap_h) | ||||||
|     api_fatal ("Couldn't create heap for child, size %d, %E", size); |     api_fatal ("Couldn't create heap for child, size %d, %E", size); | ||||||
|   newcygheap = MapViewOfFileEx (ci->cygheap_h, MVMAP_OPTIONS, 0, 0, 0, NULL); |   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); |   ProtectHandle1INH (ci->cygheap_h, passed_cygheap_h); | ||||||
|   if (!dup_later) |   if (!dup_later) | ||||||
|     dup_now (newcygheap, ci, n); |     dup_now (newcygheap, ci, n); | ||||||
|   | |||||||
| @@ -54,9 +54,12 @@ cygthread::stub (VOID *arg) | |||||||
|  |  | ||||||
|   while (1) |   while (1) | ||||||
|     { |     { | ||||||
|       const char *name = info->__name; |       if (!info->__name) | ||||||
|       if (!name) | #ifdef DEBUGGING | ||||||
| 	system_printf ("erroneous thread activation, name is non-NULL '%s'", name); | 	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 |       else | ||||||
| 	{ | 	{ | ||||||
| 	  if (!info->func || exiting) | 	  if (!info->func || exiting) | ||||||
| @@ -68,6 +71,7 @@ cygthread::stub (VOID *arg) | |||||||
|  |  | ||||||
| #ifdef DEBUGGING | #ifdef DEBUGGING | ||||||
| 	  info->func = NULL;	// catch erroneous activation | 	  info->func = NULL;	// catch erroneous activation | ||||||
|  | 	  info->__oldname = info->__name; | ||||||
| #endif | #endif | ||||||
| 	  info->__name = NULL; | 	  info->__name = NULL; | ||||||
| 	  if (info->inuse) | 	  if (info->inuse) | ||||||
| @@ -159,11 +163,16 @@ cygthread::cygthread (LPTHREAD_START_ROUTINE start, LPVOID param, | |||||||
|   else |   else | ||||||
|     { |     { | ||||||
|       stack_ptr = NULL; |       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, |       h = CreateThread (&sec_none_nih, 0, is_freerange ? simplestub : stub, | ||||||
| 			this, 0, &id); | 			this, 0, &id); | ||||||
|       if (!h) |       if (!h) | ||||||
| 	api_fatal ("thread handle not set - %p<%p>, %E", h, id); | 	api_fatal ("thread handle not set - %p<%p>, %E", h, id); | ||||||
|       thread_printf ("created thread %p", h); |       thread_printf ("created thread %p", h); | ||||||
|  |       terminated = false; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -215,9 +224,11 @@ cygthread::exit_thread () | |||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| cygthread::release () | cygthread::release (bool nuke_h) | ||||||
| { | { | ||||||
|  |   if (nuke_h) | ||||||
|     h = NULL; |     h = NULL; | ||||||
|  |   __oldname = __name; | ||||||
|   __name = NULL; |   __name = NULL; | ||||||
|   stack_ptr = NULL; |   stack_ptr = NULL; | ||||||
|   (void) InterlockedExchange (&inuse, 0); /* No longer in use */ |   (void) InterlockedExchange (&inuse, 0); /* No longer in use */ | ||||||
| @@ -227,7 +238,7 @@ cygthread::release () | |||||||
| void | void | ||||||
| cygthread::terminate_thread () | 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 |      problem is that terminate_thread could be called while a thread | ||||||
|      is terminating and either the thread could be handling its own |      is terminating and either the thread could be handling its own | ||||||
|      release or, if this is being called during exit, some other |      release or, if this is being called during exit, some other | ||||||
| @@ -239,19 +250,19 @@ cygthread::terminate_thread () | |||||||
|       ResetEvent (*this); |       ResetEvent (*this); | ||||||
|       ResetEvent (thread_sync); |       ResetEvent (thread_sync); | ||||||
|     } |     } | ||||||
|   if (!h) |   if (!inuse) | ||||||
|     return; |     return; | ||||||
|   (void) TerminateThread (h, 0); |   (void) TerminateThread (h, 0); | ||||||
|   (void) WaitForSingleObject (h, INFINITE); |   (void) WaitForSingleObject (h, INFINITE); | ||||||
|   if (!h) |   if (!inuse) | ||||||
|     return; |     return; | ||||||
|  |  | ||||||
|   CloseHandle (h); |   CloseHandle (h); | ||||||
|  |  | ||||||
|   while (h && !stack_ptr) |   while (inuse && !stack_ptr) | ||||||
|     low_priority_sleep (0); |     low_priority_sleep (0); | ||||||
|  |  | ||||||
|   if (!h) |   if (!inuse) | ||||||
|     return; |     return; | ||||||
|  |  | ||||||
|   MEMORY_BASIC_INFORMATION m; |   MEMORY_BASIC_INFORMATION m; | ||||||
| @@ -264,10 +275,17 @@ cygthread::terminate_thread () | |||||||
|     debug_printf ("VirtualFree of allocation base %p<%p> failed, %E", |     debug_printf ("VirtualFree of allocation base %p<%p> failed, %E", | ||||||
| 		   stack_ptr, m.AllocationBase); | 		   stack_ptr, m.AllocationBase); | ||||||
|  |  | ||||||
|  |   if (!inuse) | ||||||
|  |     /* nothing */; | ||||||
|   if (is_freerange) |   if (is_freerange) | ||||||
|     free (this); |     free (this); | ||||||
|   else |   else | ||||||
|     release (); |     { | ||||||
|  | #ifdef DEBUGGING | ||||||
|  |       terminated = true; | ||||||
|  | #endif | ||||||
|  |       release (true); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Detach the cygthread from the current thread.  Note that the | /* Detach the cygthread from the current thread.  Note that the | ||||||
|   | |||||||
| @@ -18,6 +18,10 @@ class cygthread | |||||||
|   HANDLE thread_sync; |   HANDLE thread_sync; | ||||||
|   void *stack_ptr; |   void *stack_ptr; | ||||||
|   const char *__name; |   const char *__name; | ||||||
|  | #ifdef DEBUGGING | ||||||
|  |   const char *__oldname; | ||||||
|  |   bool terminated; | ||||||
|  | #endif | ||||||
|   LPTHREAD_START_ROUTINE func; |   LPTHREAD_START_ROUTINE func; | ||||||
|   VOID *arg; |   VOID *arg; | ||||||
|   bool is_freerange; |   bool is_freerange; | ||||||
| @@ -28,7 +32,7 @@ class cygthread | |||||||
|   static DWORD WINAPI simplestub (VOID *); |   static DWORD WINAPI simplestub (VOID *); | ||||||
|   static DWORD main_thread_id; |   static DWORD main_thread_id; | ||||||
|   static const char * name (DWORD = 0); |   static const char * name (DWORD = 0); | ||||||
|   void release (); |   void release (bool); | ||||||
|   cygthread (LPTHREAD_START_ROUTINE, LPVOID, const char *); |   cygthread (LPTHREAD_START_ROUTINE, LPVOID, const char *); | ||||||
|   cygthread () {}; |   cygthread () {}; | ||||||
|   static void init (); |   static void init (); | ||||||
|   | |||||||
| @@ -764,7 +764,7 @@ proc_waiter (void *arg) | |||||||
|  |  | ||||||
|   sigproc_printf ("exiting wait thread for pid %d", pid); |   sigproc_printf ("exiting wait thread for pid %d", pid); | ||||||
|   vchild.wait_thread = NULL; |   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; |   return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user