Gabriella439 / Haskell-Pipes-Safe-Library

Safety for the pipes ecosystem
BSD 3-Clause "New" or "Revised" License
26 stars 21 forks source link

MonadBaseControl and other instances for SafeT #23

Closed jwiegley closed 9 years ago

jwiegley commented 9 years ago

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 uses lifted-base and lifted-async to manage concurrency and exception handling. These require MonadBaseControl IO.

jwiegley commented 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.

Gabriella439 commented 9 years ago

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?

jwiegley commented 9 years ago

@Gabriel439 Probably not anymore, since 7.10. I'm happy to drop that, and users <7.10 will simply need to upgrade.

Gabriella439 commented 9 years ago

Sounds good to me

jwiegley commented 9 years ago

Thanks!

Gabriella439 commented 9 years ago

Thank you! Would you like me to upload this right now or do you have any other changes you would like to add first?

jwiegley commented 9 years ago

No, I'm done in pipes-safe for now. I'll let you know if anything else comes up.

jwiegley commented 9 years ago

By which I guess I mean to say, yes, an upload would be great. :)

Gabriella439 commented 9 years ago

Alright, this is up on Hackage as pipes-safe 2.2.3

jwiegley commented 9 years ago

Thanks again, @Gabriel439! pipes-async 0.1.0 has been uploaded too.