Per-generation lists of weak pointers

Akio Takano tkn.akio at
Sun May 5 11:10:45 CEST 2013

On Sat, May 4, 2013 at 8:50 AM, Edward Z. Yang <ezyang at>wrote:

> Akio, your derefWeak WHITEHOLE fix looks really weird. I don't
> know what the right pattern is, but it seems like asking for trouble
> when there are multiple concurrent derefs:
>     if (info == stg_WHITEHOLE_info) {
>       ("ptr" info) = ccall lockClosure(w "ptr");
>        unlockClosure(w, info);
>     }
I don't see what the problem is, could you elaborate?

The purpose of the fix was to prevent a sequence like this:

- w is a dead weak pointer.
- Thread A: finalizeWeak# w.
- Thread A: finalizeWeak#  calls lockClosure(w), overwriting w->info with
- 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.

> > 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

> > I haven't got around to looking at this, but I see Edward is on the case
> > with some code review.  Do you think I should look at it before it goes
> in?
> Now you're asking for it :)  I would always be interested in seeing if I
> missed anything.
> Cheers,
> Edward
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the ghc-devs mailing list