]> granicus.if.org Git - gc/commitdiff
Fix assertion violation in return_single_freelist in child process
authorIvan Maidanski <ivmai@mail.ru>
Mon, 28 Aug 2017 08:26:51 +0000 (11:26 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Thu, 28 Sep 2017 08:44:50 +0000 (11:44 +0300)
Issue #171 (bdwgc).

GC_destroy_thread_local cannot be called from a thread other than
the current one.

* pthread_support.c [CAN_HANDLE_FORK && THREAD_LOCAL_ALLOC]
(GC_remove_all_threads_but_me): Do not call GC_destroy_thread_local;
add comment.
* win32_threads.c [CAN_HANDLE_FORK && THREAD_LOCAL_ALLOC]
(GC_remove_all_threads_but_me): Likewise.
* thread_local_alloc.c [THREAD_LOCAL_ALLOC] (GC_destroy_thread_local):
Update comment.

pthread_support.c
thread_local_alloc.c
win32_threads.c

index a4143169398f83eb24238f8038c4fd929e5d741b..f3d7065a2b0e4933168057e7446aef97fd6525c6 100644 (file)
@@ -773,7 +773,12 @@ STATIC void GC_remove_all_threads_but_me(void)
         } else {
 #         ifdef THREAD_LOCAL_ALLOC
             if (!(p -> flags & FINISHED)) {
-              GC_destroy_thread_local(&(p->tlfs));
+              /* Cannot call GC_destroy_thread_local here.  The free    */
+              /* lists may be in an inconsistent state (as thread p may */
+              /* be updating one of the lists by GC_generic_malloc_many */
+              /* or GC_FAST_MALLOC_GRANS when fork is invoked).         */
+              /* This should not be a problem because the lost elements */
+              /* of the free lists will be collected during GC.         */
               GC_remove_specific_after_fork(GC_thread_key, p -> id);
             }
 #         endif
index 3951fe711ca761d38a9303af1a3514e313f19aad..25568b46b8d74438f7f0b39447d5dbfc01adc852 100644 (file)
@@ -129,8 +129,7 @@ GC_INNER void GC_destroy_thread_local(GC_tlfs p)
 {
     int k;
 
-    /* We currently only do this from the thread itself or from */
-    /* the fork handler for a child process.                    */
+    /* We currently only do this from the thread itself.        */
     GC_STATIC_ASSERT(THREAD_FREELISTS_KINDS <= MAXOBJKINDS);
     for (k = 0; k < THREAD_FREELISTS_KINDS; ++k) {
         if (k == (int)GC_n_kinds)
index 634ebf0a555ede3615e8075239b7c7d6848af8d2..97e8c6ea86e0e47bbb3ca45e11b18f1bea03543c 100644 (file)
@@ -1033,7 +1033,8 @@ GC_API void * GC_CALL GC_call_with_gc_active(GC_fn_type fn,
           } else {
 #           ifdef THREAD_LOCAL_ALLOC
               if ((p -> flags & FINISHED) == 0) {
-                GC_destroy_thread_local(&p->tlfs);
+                /* Cannot call GC_destroy_thread_local here (see the    */
+                /* corresponding comment in pthread_support.c).         */
                 GC_remove_specific_after_fork(GC_thread_key, p -> pthread_id);
               }
 #           endif