Unmask async exceptions in STM transaction

I have a function that posts a request to an STM channel and then blocks the thread waiting for that request's completion. If my blocked thread is terminated by an async exception then I want to post a cancellation request to that STM channel. It currently looks like this:

runRequest channel request = mask $ restore -> do
  (reqId, resultVar) <- restore . atomically $ requestPostSTM channel request
  onException
    (restore . atomically $ do
      maybeResult <- readTVar resultVar
      case maybeResult of
        Just x -> return x
        Nothing -> retry)
    (atomically $ requestCancelSTM channel reqId)

This is almost what I need, but there is a small possibility that async exception would arrive right after requestPostSTM transaction succeeds, but still before we exit restore block. If this happens, then I will have my request posted, but wouldn't be able to post a cancellation for it.

Ideally I would like to change the second line to something like

  (reqId, resultVar) <- atomically . restore $ requestPostSTM channel request

This way I would be sure that no async exception could sneak in after I have requestPostSTM transaction commited. But this, of course, doesn't compile because restore is IO a -> IO a , not STM a -> STM a .

Is there any way I could unmask async exceptions only for duration of my STM transaction? Or maybe another way to have a guarantee that either an async exception arrives and my first STM transaction aborts or my first STM transaction commits and no async exception could terminate my thread until I install a handler for it with onException ?


It is better to call requestPostSTM with async exceptions masked. All STM actions, that retries, are interruptible, so they will be aborted in case of async exception, yet exception can't arrive in unexpected point. The rule is: if your action allocates resource (ie something, that should be deallocated), then you should run it with async exceptions masked, and rely on interruptible actions to abort the action at some known points (or pull async exceptions with allowInterrupt manually).

链接地址: http://www.djcxy.com/p/81466.html

上一篇: 如何水平显示“div”?

下一篇: 在STM事务中取消屏蔽异步异常