
On 05/07/15 21:54, Silvio Frischknecht wrote:
I need a onCommit functionality for stm. I know there is the stm-io-hooks [1] package. But it seems so big for such a small thing and then I have to translate everything to their monad. lift lift lift ...
So I thought of a little hack to solve the issue and I'm wondering if this is safe to use. My understanding of stm internals is very limited. It's basically just a TChan with IO actions in it and there is another thread waiting to execute anything inserted into it.
import Control.Concurrent.STM.TChan
onCommitChan :: TChan (IO ()) {-# NOINLINE onCommit #-} onCommitChan = unsafePerformIO $ do chan <- newTChanIO forkIO $ forever $ atomically $ readTChan chan return chan
onCommit :: IO () -> STM () onCommit = writeTChan onCommitChan
Leaving aside the question of unsafePerformIO, which is a bad idea, this will more-or-less work, but I suppose the question is what you mean by "safe to use". You might want to think about exception safety: for example, if one of the IO actions written to the channel throws an exception, it will bring down the worker thread, and subsequent onCommit actions will be silently lost. Or if an IO action blocks (or just runs slowly) other actions may be arbitrarily delayed. Depending on your application, this may or may not be acceptable. Hope this helps, Adam -- Adam Gundry, Haskell Consultant Well-Typed LLP, http://www.well-typed.com/