Re: Per-generation lists of weak pointers

Thank you for your comments, I updated the patches on the ticket (comment
changes only).
http://hackage.haskell.org/trac/ghc/ticket/7847
On Sun, May 5, 2013 at 7:50 PM, Edward Z. Yang
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.
OK, but you should add a comment about what this code is doing.
Done.
(You will also unnecessarily lock when GET_INFO snags a transient whitehole),
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.
Edward
participants (1)
-
Akio Takano