Per-generation lists of weak pointers
tkn.akio at gmail.com
Mon May 6 11:28:48 CEST 2013
Thank you for your comments, I updated the patches on the ticket (comment
On Sun, May 5, 2013 at 7:50 PM, Edward Z. Yang <ezyang at cs.stanford.edu>wrote:
> > 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
> > as stg_DEAD_WEAK_info, it thinks w is alive.
> > The problem was that if deRefWeak# saw stg_WHITEHOLE_info, it was not
> > whether the weak pointer was alive or not. So my fix adds a call to
> > lockClosure, which never returns stg_WHITEHOLE_info.
> OK, but you should add a comment about what this code is doing.
> (You will also unnecessarily lock when GET_INFO snags a transient
> > > > 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.
> Sorry, I still don't understand. Tracing the code execution, no change
> is made to the IORef when Finalizers is CFinalizers?
When addCFinalizerToWeak fails, some other thread must have called
foreignPtrFinalizer, and it must have replaced the content of the IORef
before calling finalizeWeak#. I updated the comment to mention this logic.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the ghc-devs