Per-generation lists of weak pointers

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


On Sat, May 4, 2013 at 8:50 AM, Edward Z. Yang <ezyang at cs.stanford.edu>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
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.


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


>
> > 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: <http://www.haskell.org/pipermail/ghc-devs/attachments/20130505/c215f4c6/attachment.htm>


More information about the ghc-devs mailing list