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
path: root/winsup
diff options
context:
space:
mode:
authorRobert Collins <rbtcollins@hotmail.com>2002-06-05 16:39:55 +0400
committerRobert Collins <rbtcollins@hotmail.com>2002-06-05 16:39:55 +0400
commite9259cb240fbd18e5e47617a6e236a26107d6ded (patch)
tree15e2d957d71044ab502c9033249a9e8ada6e45ae /winsup
parenteceee297d5c2f508e247f803b32bf4817716bc38 (diff)
/tmp/cvs610a0efc.1
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog16
-rw-r--r--winsup/cygwin/thread.cc38
-rw-r--r--winsup/cygwin/thread.h1
3 files changed, 48 insertions, 7 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index fc0a07ad9..e4d0a3e65 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,19 @@
+2002-04-18 Thomas Pfaff <tpfaff@gmx.net>
+
+ * thread.h (pthread::joiner): New member.
+ * thread.cc (pthread::pthread): Initialize joiner to NULL
+ (pthread::create): Increment of thread counter moved from
+ __pthread_create to this location.
+ (__pthread_create): Increment thread counter removed.
+ (thread_init_wrapper): Set joiner to self when thread was created
+ detached.
+ (__pthread_exit): delete thread when it is detached and not
+ joined.
+ (__pthread_join): Check for deadlock and delete thread when it has
+ terminated.
+ (__pthread_detach): Set joiner to self when thread state
+ changed to detached.
+
2002-06-05 Corinna Vinschen <corinna@vinschen.de>
* grp.cc (read_etc_group): When emulating nonexisting group file on
diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc
index c0cd26c3e..5428d674d 100644
--- a/winsup/cygwin/thread.cc
+++ b/winsup/cygwin/thread.cc
@@ -344,7 +344,7 @@ MTinterface::fixup_after_fork (void)
}
pthread::pthread ():verifyable_object (PTHREAD_MAGIC), win32_obj_id (0),
-cancelstate (0), canceltype (0)
+cancelstate (0), canceltype (0), joiner(NULL)
{
}
@@ -381,6 +381,7 @@ pthread::create (void *(*func) (void *), pthread_attr *newattr,
magic = 0;
else
{
+ InterlockedIncrement (&MT_INTERFACE->threadcount);
/*FIXME: set the priority appropriately for system contention scope */
if (attr.inheritsched == PTHREAD_EXPLICIT_SCHED)
{
@@ -908,6 +909,10 @@ thread_init_wrapper (void *_arg)
/*the OS doesn't check this for <= 64 Tls entries (pre win2k) */
TlsSetValue (MT_INTERFACE->thread_self_dwTlsIndex, thread);
+ // if thread is detached force cleanup on exit
+ if (thread->attr.joinable == PTHREAD_CREATE_DETACHED)
+ thread->joiner = __pthread_self();
+
#ifdef _CYG_THREAD_FAILSAFE
if (_REENT == _impure_ptr)
system_printf ("local storage for thread isn't setup correctly");
@@ -945,7 +950,6 @@ __pthread_create (pthread_t *thread, const pthread_attr_t *attr,
*thread = NULL;
return EAGAIN;
}
- InterlockedIncrement (&MT_INTERFACE->threadcount);
return 0;
}
@@ -1491,11 +1495,16 @@ __pthread_attr_destroy (pthread_attr_t *attr)
void
__pthread_exit (void *value_ptr)
{
- class pthread *thread = __pthread_self ();
+ pthread_t thread = __pthread_self ();
MT_INTERFACE->destructors.IterateNull ();
- thread->return_ptr = value_ptr;
+ // cleanup if thread is in detached state and not joined
+ if( __pthread_equal(&thread->joiner, &thread ) )
+ delete thread;
+ else
+ thread->return_ptr = value_ptr;
+
if (InterlockedDecrement (&MT_INTERFACE->threadcount) == 0)
exit (0);
else
@@ -1505,6 +1514,8 @@ __pthread_exit (void *value_ptr)
int
__pthread_join (pthread_t *thread, void **return_val)
{
+ pthread_t joiner = __pthread_self();
+
/*FIXME: wait on the thread cancellation event as well - we are a cancellation point*/
if (verifyable_object_isvalid (thread, PTHREAD_MAGIC) != VALID_OBJECT)
return ESRCH;
@@ -1512,15 +1523,26 @@ __pthread_join (pthread_t *thread, void **return_val)
if ((*thread)->attr.joinable == PTHREAD_CREATE_DETACHED)
{
if (return_val)
- *return_val = NULL;
+ *return_val = NULL;
return EINVAL;
}
+
+ else if( __pthread_equal(thread, &joiner ) )
+ {
+ if (return_val)
+ *return_val = NULL;
+ return EDEADLK;
+ }
+
else
{
(*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
+ (*thread)->joiner = joiner;
WaitForSingleObject ((*thread)->win32_obj_id, INFINITE);
if (return_val)
- *return_val = (*thread)->return_ptr;
+ *return_val = (*thread)->return_ptr;
+ // cleanup
+ delete (*thread);
} /*End if */
pthread_testcancel ();
@@ -1536,11 +1558,13 @@ __pthread_detach (pthread_t *thread)
if ((*thread)->attr.joinable == PTHREAD_CREATE_DETACHED)
{
- (*thread)->return_ptr = NULL;
return EINVAL;
}
(*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
+ // force cleanup on exit
+ (*thread)->joiner = *thread;
+
return 0;
}
diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h
index 5004c950e..b71c3a31b 100644
--- a/winsup/cygwin/thread.h
+++ b/winsup/cygwin/thread.h
@@ -239,6 +239,7 @@ public:
void *return_ptr;
bool suspended;
int cancelstate, canceltype;
+ pthread_t joiner;
// int joinable;
DWORD GetThreadId ()