Don't call DEAD_WEAK finalizer again on shutdown (#7170)
[ghc.git] / rts / sm / MarkWeak.c
index b8ec453..60ac53f 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Documentation on the architecture of the Garbage Collector can be
  * found in the online commentary:
- * 
+ *
  *   http://ghc.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage/GC
  *
  * ---------------------------------------------------------------------------*/
@@ -60,7 +60,7 @@
      threads from the all_threads and main thread lists are the
      weakest of all: a pointers from the finalizer of a dead weak
      pointer can keep a thread alive.  Any threads found to be unreachable
-     are evacuated and placed on the resurrected_threads list so we 
+     are evacuated and placed on the resurrected_threads list so we
      can send them a signal later.
 
    - weak_stage == WeakDone
@@ -102,7 +102,7 @@ initWeakForGC(void)
     resurrected_threads = END_TSO_QUEUE;
 }
 
-rtsBool 
+rtsBool
 traverseWeakPtrList(void)
 {
   rtsBool flag = rtsFalse;
@@ -119,7 +119,7 @@ traverseWeakPtrList(void)
        */
   {
       nat g;
-         
+
       for (g = 0; g <= N; g++) {
           tidyThreadList(&generations[g]);
       }
@@ -131,7 +131,7 @@ traverseWeakPtrList(void)
               flag = rtsTrue;
           }
       }
-      
+
       // if we evacuated anything new, we must scavenge thoroughly
       // before we can determine which threads are unreachable.
       if (flag) return rtsTrue;
@@ -165,7 +165,7 @@ traverseWeakPtrList(void)
               flag = rtsTrue;
           }
       }
-      
+
       /* If we didn't make any changes, then we can go round and kill all
        * the dead weak pointers.  The dead_weak_ptr list is used as a list
        * of pending finalizers later on.
@@ -186,7 +186,7 @@ traverseWeakPtrList(void)
       return rtsTrue;
   }
 }
-  
+
 static void collectDeadWeakPtrs (generation *gen)
 {
     StgWeak *w, *next_w;
@@ -205,7 +205,7 @@ static rtsBool resurrectUnreachableThreads (generation *gen)
 
     for (t = gen->old_threads; t != END_TSO_QUEUE; t = next) {
         next = t->global_link;
-        
+
         // ThreadFinished and ThreadComplete: we have to keep
         // these on the all_threads list until they
         // become garbage, because they might get
@@ -306,16 +306,16 @@ static void tidyThreadList (generation *gen)
     prev = &gen->old_threads;
 
     for (t = gen->old_threads; t != END_TSO_QUEUE; t = next) {
-             
+
         tmp = (StgTSO *)isAlive((StgClosure *)t);
-       
+
         if (tmp != NULL) {
             t = tmp;
         }
-        
+
         ASSERT(get_itbl((StgClosure *)t)->type == TSO);
         next = t->global_link;
-        
+
         // if the thread is not masking exceptions but there are
         // pending exceptions on its queue, then something has gone
         // wrong.  However, pending exceptions are OK if there is an
@@ -324,16 +324,16 @@ static void tidyThreadList (generation *gen)
                || t->why_blocked == BlockedOnCCall
                || t->why_blocked == BlockedOnCCall_Interruptible
                || (t->flags & TSO_BLOCKEX));
-        
+
         if (tmp == NULL) {
             // not alive (yet): leave this thread on the
             // old_all_threads list.
             prev = &(t->global_link);
-        } 
+        }
         else {
             // alive
             *prev = next;
-            
+
             // move this thread onto the correct threads list.
             generation *new_gen;
             new_gen = Bdescr((P_)t)->gen;
@@ -348,7 +348,8 @@ static void checkWeakPtrSanity(StgWeak *hd, StgWeak *tl)
 {
     StgWeak *w, *prev;
     for (w = hd; w != NULL; prev = w, w = w->link) {
-        ASSERT(INFO_PTR_TO_STRUCT(UNTAG_CLOSURE((StgClosure*)w)->header.info)->type == WEAK);
+        ASSERT(INFO_PTR_TO_STRUCT(UNTAG_CLOSURE((StgClosure*)w)->header.info)->type == WEAK
+            || UNTAG_CLOSURE((StgClosure*)w)->header.info == &stg_DEAD_WEAK_info);
         checkClosure((StgClosure*)w);
     }
     if (tl != NULL) {
@@ -416,11 +417,3 @@ markWeakPtrList ( void )
     }
 }
 
-
-// Local Variables:
-// mode: C
-// fill-column: 80
-// indent-tabs-mode: nil
-// c-basic-offset: 4
-// buffer-file-coding-system: utf-8-unix
-// End: