[reactive] Re: black hole detection and concurrency
Simon Marlow
marlowsd at gmail.com
Tue Jan 6 09:45:41 EST 2009
Isaac Dupree wrote:
> therefore mapException is equally buggy!
>
>> mapException :: (Exception e1, Exception e2) => (e1 -> e2) -> a -> a
>> mapException f v = unsafePerformIO (catch (evaluate v)
>> (\x -> throw (f x)))
>
> If it maps an asynchronous exception.. and it's re-thrown as
> synchronous... the same non-resumability happens! mapException is a
> particular culprit because of the unsafePerformIO (so you had a good
> reason to expect resumability, since it's for a pure computation, not in
> IO)
>
> - does anyone use mapException?
>
> - is there some reason that we don't have all "throw"s (synch. or
> asynch.) "patch up" the thunks? (memory leaks or serious inefficiency
> or something?)
In theory you could get a nasty space leak, but it's quite unlikely. When
an exception is thrown, instead of just updating each thunk with "raise#
DivByZero" for example, we would save the current computation in the heap
to be restarted if the thunk was ever evaluated again. If the current
computation refers to a large amount of heap data, technically that's a
space leak.
So one way to work around this would be to do all rethrows using throwTo.
In most cases this will have no effect, because the rethrows happen in IO
code which normally has no enclosing thunks, but in the case of
mapException and unsafePerformIO it will fix (or work around) the problems
we have with re-throwing async exceptions.
Cheers,
Simon
More information about the Glasgow-haskell-users
mailing list