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>
+
* cygthread.cc (cygthread::stub): Make diagnostic output more informative.
2004-12-22 Christopher Faylor <cgf@timesys.com>
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);
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)
#ifdef DEBUGGING
info->func = NULL; // catch erroneous activation
+ info->__oldname = info->__name;
#endif
info->__name = NULL;
if (info->inuse)
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;
}
}
}
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 */
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
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;
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