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

Reply via email to