Fix pthread_join when thread is registered in thread key destructor
authorIvan Maidanski <ivmai@mail.ru>
Tue, 26 Sep 2017 08:44:44 +0000 (11:44 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 26 Sep 2017 08:44:44 +0000 (11:44 +0300)
* pthread_support.c (WRAP_FUNC(pthread_join)): Remove assertion that
thread is finished; call GC_delete_gc_thread only if thread is
finished; add comment.
* win32_threads.c [GC_PTHREADS] (GC_pthread_join): Call
GC_delete_gc_thread_no_free and GC_INTERNAL_FREE only if thread is
finished.

pthread_support.c
win32_threads.c

index 2694ec8..2fdcbb8 100644 (file)
@@ -1516,9 +1516,11 @@ GC_API int WRAP_FUNC(pthread_join)(pthread_t thread, void **retval)
 # endif
     if (result == 0) {
         LOCK();
-        /* Here the pthread thread id may have been recycled. */
-        GC_ASSERT((t -> flags & FINISHED) != 0);
-        GC_delete_gc_thread(t);
+        /* Here the pthread thread id may have been recycled.           */
+        /* Delete the thread from GC_threads (unless it has been        */
+        /* registered again from the client thread key destructor).     */
+        if ((t -> flags & FINISHED) != 0)
+          GC_delete_gc_thread(t);
         UNLOCK();
     }
     return result;
index b822dcd..e89c0b1 100644 (file)
@@ -2559,8 +2559,10 @@ GC_INNER void GC_thr_init(void)
 #     endif
 
       LOCK();
+      if ((t -> flags & FINISHED) != 0) {
         GC_delete_gc_thread_no_free(t);
         GC_INTERNAL_FREE(t);
+      }
       UNLOCK();
     }