
On Fri, Sep 5, 2014 at 11:37 AM, Herbert Valerio Riedel
Hello,
I'm forwarding this on behalf of Edsko:
-------------------- Start of forwarded message -------------------- [...]
Hi Herbert,
...and I'd like to point your attention to yet another related proposal that came in yesterday:
Subject: Proposal: Use uninterruptibleMask for cleanup actions in Control.Exception
http://thread.gmane.org/gmane.comp.lang.haskell.libraries/22775
Hmmm, I thought I was subscribed to libraries@. It seems I wasn’t. I subscribed earlier today but haven’t got the confirmation email yetI (?). Perhaps you can forward my reply for now?
Anyhow, I’m not convinced about this proposal. uninterruptibleMask is rather crude. It would be one thing to block, say, timeout signals during resource cleanup (perhaps), but uninterruptibleMask blocks _all_ asynchronous exceptions, including stack overflow and heap overflow. I don’t think that the _default_ behaviour of bracket should be to disable those.
I just tested a little program that stack-overflows within an uninterruptibleMask_. The exception doesn't seem to be blocked. Can you(he?) give an example of the actual problem?
Note also that in the
bracket takeMVar putMVar
example, the putMVar is _NOT_ interruptible. By definition, putMVar is interruptible _only_ if the resource is not available. Since the takeMVar succeeded, the MVar must be empty at the time of the putMVar
Of course not! Different threads may have putMVar during the bracket. Typical MVar use will not do this, but it's certainly a possible use case that is broken. I think the fact people are missing this bug is more evidence that this behavior is a problem. and hence it cannot be interrupted. (This is assuming of course that
there are no putMVars in the body of the bracket, but if you’re doing that, you have bigger problems..). Incidentally, if that behavior of putMVar is not in fact the case, then that is a bug in putMVar, not in bracket.
The hClose example ironically _is_ an example, though it doesn’t look like one — Merijn is right, it uses an MVar under the hood and in fact it does a withMVar, which is interruptible, of course — in case somebody else happens to have the file handle at that time. But again, I’m not sure what the right answer is. I sort of feel that these file operations should _not_ be interruptible. The fact that they use MVars under the hood makes them so, but perhaps that could be considered a bug (and they should do some uninterruptibleMasking of their own) — certainly, as far as I know, it’s nowhere actually _documented_ that these operations are interruptible and most people don’t think of them as such.
But this seems like a weird position to have. On the one hand, you are claiming that making the cleanup uninterruptible is too crude. On the other hand, you're claiming that all cleanup handlers that happen to be interruptible are a bug, each. These positions contradict.
I’m not sure to be honest. I would like Simon Marlow’s opinion here. But my feeling right now is that I’d vote against this, but to try and make sure that the operations we use in cleanup handlers are, in fact, not interruptible.
The question is what do you want to do with cleanup handlers that are still interruptible? I think the only valid solutions are: A) Mask them uninterruptible as I suggest B) Raise a runtime error (or at least a warning) that this is a bug that should be fixed by making sure that the cleanup handlers are not interruptible, manually. Leaving the current behavior is the worst of all worlds.
-E -------------------- End of forwarded message --------------------
-- Eyal