Closed jwiegley closed 9 years ago
Oh, and the reason we can't have MonadTransControl
, MonadReader
or MonadRWS
: ResourceT
only executes IO
finalizers, while SafeT
allows finalizers that execute in whatever monad is underneath SafeT
. This means we have values of type m ()
in the reader environment, and we'd need MonadIO
to map those from m -> n
, which we don't have.
Yeah, I'm happy to merge this. It looks like this fails on older versions of ghc
because it can't derive the Typeable
instance. Do we need that instance, though?
@Gabriel439 Probably not anymore, since 7.10. I'm happy to drop that, and users <7.10 will simply need to upgrade.
Sounds good to me
Thanks!
Thank you! Would you like me to upload this right now or do you have any other changes you would like to add first?
No, I'm done in pipes-safe
for now. I'll let you know if anything else comes up.
By which I guess I mean to say, yes, an upload would be great. :)
Alright, this is up on Hackage as pipes-safe 2.2.3
Thanks again, @Gabriel439! pipes-async
0.1.0 has been uploaded too.
A main difference between SafeT's implementation of MonadBaseControl, and that of ResourceT: ResourceT allows a reference counting mechanism so that multiple threads can share the same resource environment, but where resources are only freed once the last thread has finished executing.
I'm not sure yet if we need this behavior, so I haven't coded in support (though it will be fairly easy to add later). Instead, and as before, runSafeT governs the lifetime of resources. If you spawn threads in a runSafeT block and they allocate resources, those resources are freed when runSafeT ends, even if those threads are still running (which means they could now reference freed resources). If the child threads attempt to acquire or release resources beyond that point, it raises an error.
Therefore, the only safe way to mix forkIO with SafeT (via MonadBaseControl) is to ensure that the thread executing runSafeT either waits until all other threads have been completed before allowing runSafeT to complete, or cancels all those threads before it exits.
@Gabriel439 The reason I'm submitting this support is that I'm working on a
pipes-async
library, supporting higher-level constructs like a dead simple>&>
operator, which useslifted-base
andlifted-async
to manage concurrency and exception handling. These requireMonadBaseControl IO
.