horrible realization
This commit is contained in:
parent
24ff5e2b29
commit
8a824147e4
1 changed files with 54 additions and 0 deletions
|
@ -0,0 +1,54 @@
|
||||||
|
[[!comment format=mdwn
|
||||||
|
username="joey"
|
||||||
|
subject="""comment 16"""
|
||||||
|
date="2020-06-09T17:53:08Z"
|
||||||
|
content="""
|
||||||
|
A possible problem is code like this:
|
||||||
|
|
||||||
|
bracket setup cleanup
|
||||||
|
where
|
||||||
|
setup = blockingOperationFoo >>= blockingOperationBar
|
||||||
|
|
||||||
|
The problem is that async exceptions are not fully
|
||||||
|
masked by bracket. See Control.Exception's
|
||||||
|
discussion of "Interruptible operations".
|
||||||
|
|
||||||
|
All the blocking operations in that example can still receive an async
|
||||||
|
exception.
|
||||||
|
|
||||||
|
If blockingOperationFoo opens a handle say, and then blockingOperationBar
|
||||||
|
is hit by an async exception, then cleanup will never run! The handle
|
||||||
|
will be left open.
|
||||||
|
|
||||||
|
Solution is `uninterruptibleMask_ setup`. Although of course this means
|
||||||
|
it will block until both operations finish, so they should not be long
|
||||||
|
duration operations. Alternatively, untangle the two operations, and nest
|
||||||
|
brackets.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Also, if the cleanup action of bracket is an interruptable operation, it too
|
||||||
|
can receive an async exception.
|
||||||
|
|
||||||
|
This doesn't result in withFile leaking file handles when it brackets hClose,
|
||||||
|
but I think perhaps only because the GC closes them.
|
||||||
|
But it looks like
|
||||||
|
[withCreateProcess has a bug](https://github.com/haskell/process/issues/183).
|
||||||
|
|
||||||
|
And it's easy to construct cases where a compound cleanup action leaks:
|
||||||
|
|
||||||
|
main = forever $ do
|
||||||
|
let p = proc "cat" []
|
||||||
|
a <- async $ bracket
|
||||||
|
(createProcess p)
|
||||||
|
(\p -> threadDelay 10000 >> cleanupProcess p)
|
||||||
|
(\_ -> print "started process")
|
||||||
|
threadDelay 1000
|
||||||
|
cancel a
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
So, seems all uses of bracket and things like it (onException etc)
|
||||||
|
will need to be audited for blocking operations, or just make
|
||||||
|
uninterruptibleMask_ be used everywhere. Ugh.
|
||||||
|
"""]]
|
Loading…
Add table
Add a link
Reference in a new issue