summaryrefslogtreecommitdiff
path: root/ptw32_threadDestroy.c
diff options
context:
space:
mode:
authorrpj <rpj>2003-08-14 08:53:17 +0000
committerrpj <rpj>2003-08-14 08:53:17 +0000
commita50745ec922a917513029f3f87bf820827b43f29 (patch)
tree1e221862e0550d163baef12d17634430ae677824 /ptw32_threadDestroy.c
parent414f4bd7e70d94025576d9264c86da63c506f6ca (diff)
Reuse of thread IDs, improved thread ID validation, new tests, bug fixes.
Diffstat (limited to 'ptw32_threadDestroy.c')
-rw-r--r--ptw32_threadDestroy.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/ptw32_threadDestroy.c b/ptw32_threadDestroy.c
index 1c503a6..18dc6a9 100644
--- a/ptw32_threadDestroy.c
+++ b/ptw32_threadDestroy.c
@@ -42,6 +42,8 @@
void
ptw32_threadDestroy (pthread_t thread)
{
+ struct pthread_t_ threadCopy;
+
if (thread != NULL)
{
(void) pthread_mutex_lock(&thread->cancelLock);
@@ -50,22 +52,33 @@ ptw32_threadDestroy (pthread_t thread)
ptw32_callUserDestroyRoutines (thread);
- if (thread->cancelEvent != NULL)
- {
- CloseHandle (thread->cancelEvent);
- }
+ /*
+ * Copy thread state so that the thread can be atomically NULLed.
+ */
+ memcpy(&threadCopy, thread, sizeof(threadCopy));
+
+ /*
+ * Thread ID structs are never freed. They're NULLed and reused.
+ * This also sets the thread to PThreadStateInitial (invalid).
+ */
+ ptw32_threadReusePush(thread);
+
+ /* Now work on the copy. */
+ if (threadCopy.cancelEvent != NULL)
+ {
+ CloseHandle (threadCopy.cancelEvent);
+ }
- (void) pthread_mutex_destroy(&thread->cancelLock);
+ (void) pthread_mutex_destroy(&threadCopy.cancelLock);
#if ! defined (__MINGW32__) || defined (__MSVCRT__)
/* See documentation for endthread vs endthreadex. */
- if( thread->threadH != 0 )
- {
- CloseHandle( thread->threadH );
- }
+ if( threadCopy.threadH != 0 )
+ {
+ CloseHandle( threadCopy.threadH );
+ }
#endif
- free (thread);
}
} /* ptw32_threadDestroy */