Commit cec899d9 authored by Simon Marlow's avatar Simon Marlow
Browse files

Retain ordering of finalizers during GC (#7160)

This came up since the addition of C finalizers, since Haskell
finalizers are already stored in an explicit list.  C finalizers on
the other hand get a WEAK object each, so in order to run them in the
right order we have to make sure that list stays in the correct
order.  I hate adding new invariants, but this is the quickest way to
fix the bug for now.  A better way to fix it would be to have a single
WEAK object with a list of finaliers attached to it, and a primop
for adding finalizers to the list.
parent 2fe4dbc7
......@@ -78,6 +78,7 @@ static WeakStage weak_stage;
/* Weak pointers
*/
StgWeak *old_weak_ptr_list; // also pending finaliser list
StgWeak *weak_ptr_list_tail;
// List of threads found to be unreachable
StgTSO *resurrected_threads;
......@@ -90,6 +91,7 @@ initWeakForGC(void)
{
old_weak_ptr_list = weak_ptr_list;
weak_ptr_list = NULL;
weak_ptr_list_tail = NULL;
weak_stage = WeakPtrs;
resurrected_threads = END_TSO_QUEUE;
}
......@@ -139,11 +141,18 @@ traverseWeakPtrList(void)
evacuate(&w->finalizer);
// remove this weak ptr from the old_weak_ptr list
*last_w = w->link;
// and put it on the new weak ptr list
next_w = w->link;
w->link = weak_ptr_list;
weak_ptr_list = w;
flag = rtsTrue;
next_w = w->link;
// and put it on the new weak ptr list.
// NB. we must retain the order of the weak_ptr_list (#7160)
if (weak_ptr_list == NULL) {
weak_ptr_list = w;
} else {
weak_ptr_list_tail->link = w;
}
weak_ptr_list_tail = w;
w->link = NULL;
flag = rtsTrue;
debugTrace(DEBUG_weak,
"weak pointer still alive at %p -> %p",
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment