black hole detection and concurrency
Sterling Clover
s.clover at gmail.com
Sat Dec 27 12:40:00 EST 2008
On Dec 27, 2008, at 9:02 AM, Bertram Felgenhauer wrote:
>
> The key part here is 'myThreadId >>= killThread' which throws an
> asynchronous exception to the thread itself, causing the update
> frames to be saved on the heap.
>
> Note that 'myThreadId >>= killThread' is not equivalent to
> 'throw ThreadKilled'; it is a synchronous exception and replaces
> thunks
> pointed to by the update frames by another call to the raise
> primitive -
> the result being that the exception gets rethrown whenever such a
> thunk
> is evaluated. This happens with 'finally' and 'bracket': they use
> 'throw' for re-throwing the exception.
>
> See rts/RaiseAsync.c (raiseAsync() in particular) for the gory details
> for the first case, and rts/Schedule.c, raiseExceptionHelper() for the
> second case.
>
> In the above code, there is a small window between catching the
> ThreadKilled exception and throwing it again though, where other
> exceptions may creep in. The only way I see of fixing that is to use
> 'block' and 'unblock' directly.
>
That certainly seems to do the trick for the simple example at least.
One way to reason about it better would be, instead of folding
everything into the race function, to simply modify ghc's bracket
function to give us the behavior we'd prefer (speaking of which, I
recall there's something in the works for 6.12 or so to improve
rethrowing of asynchronous exceptions?)
brackAsync before after thing =
block (do
a <- before
r <- catch
(unblock (thing a))
(\_ -> after a >> myThreadId >>= killThread >> brackAsync
before after thing )
after a
return r
)
where threadKilled ThreadKilled = Just ()
threadKilled _ = Nothing
This brackAsync just drops in to the previous code where bracket was
and appears to perform correctly. Further, if we place a trace after
the killThread, we se it gets executed once when the example is read
(i.e. a resumption) but it does not get executed if the (`seq` v) is
removed from the example So this gives me some hope that this is
actually doing what we'd like. I don't doubt it may have further
kinks however.
Cheers,
Sterl.
More information about the Glasgow-haskell-users
mailing list