> The purpose of the fix was to prevent a sequence like this:OK, but you should add a comment about what this code is doing.
>
> - w is a dead weak pointer.
> - Thread A: finalizeWeak# w.
> - Thread A: finalizeWeak# calls lockClosure(w), overwriting w->info with
> stg_WHITEHOLE_info.
> - Thread B: deRefWeak# w
> - Thread B: deRefWeak# sees stg_WHITEHOLE_info, and since it's not the same
> as stg_DEAD_WEAK_info, it thinks w is alive.
>
> The problem was that if deRefWeak# saw stg_WHITEHOLE_info, it was not clear
> whether the weak pointer was alive or not. So my fix adds a call to
> lockClosure, which never returns stg_WHITEHOLE_info.
(You will also unnecessarily lock when GET_INFO snags a transient whitehole),
Sorry, I still don't understand. Tracing the code execution, no change
> > > addForeignPtrFinalizer retries in this case.
> >
> > This can't be right; a dead weak pointer always stays dead, so won't
> > this infinite loop?
> >
>
> No. When addForeignPtrFinalizer retries, it will use a new Weak# object,
> because foreignPtrFinalizer must have been replaced the content of the
> IORef.
is made to the IORef when Finalizers is CFinalizers?
Edward