On 14/08/10 02:30, Lennart Augustsson wrote:
So it's a bug in the garbage collector. It's closing a handle that
clearly is still reachable, otherwise this would not have happened.
The handle is in fact not reachable from the roots, because the thread
that points to it is also not reachable.
More about it in this ticket:
http://hackage.haskell.org/trac/ghc/ticket/2161
Some rationale from that ticket:
"You may argue that a reference from a thread, even an unreachable one,
should keep a ForeignPtr alive. But it's equally valid to argue the
reverse: a reference from a finalizer should keep a thread alive - you
don't want a thread to be considered deadlocked if it can be unblocked
by a finalizer. We can't have both, because then a cycle between a
finalizer and a thread would never be collected even when both were
unreachable."
So while we can flip this decision, it would have other undesirable
consequences. I suppose I don't really have a good handle on how often
you want one behaviour vs. the other - feedback welcome. Either way the
GC has to do two extra phases after tracing from the roots: trace from
the finalizers and then the unreachable threads, or vice versa.
Cheers,
Simon
On Fri, Aug 13, 2010 at 10:53 AM, Simon Marlow<[email protected]> wrote:
On 12/08/2010 21:59, Yitzchak Gale wrote:
Wei Hu wrote:
nonTermination _ = blackhole where blackhole = blackhole
My original example was actually:
process :: String -> String
process = let x = x in x
Ah yes, that works too. But other similar versions don't, like this one:
process :: String -> String
process _ = let x = x in x
Hence why I added the "tail" in my version.
So what happens is this:
- the recursive definition causes the main thread to block on itself
(known as a "black hole")
- the program is deadlocked (no threads to run), so the runtime
invokes the GC to see if any threads are unreachable
- the GC finds that
(a) the main thread is unreachable and blocked on a blackhole, so it
gets a NonTermination exception
(b) the Handle is unreachable, so its finalizer is started
- the finalizer runs first, and closes the Handle
- the main thread runs next, and the exception handler for writeFile
tries to close the Handle, which has already been finalized
Really hClose shouldn't complain about a finalized handle, I'll see if I can
fix that.
Cheers,
Simon
_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe