How do you ensure a socket get closed in the event of an exception while retaining the ability to kill the thread that is waiting for connections on that socket?
I can only think of solutions that provide one or the other, not both:
Using bracket accept close ... to guarantee cleanup masks async exceptions and prevents another thread from killing it
Using conn <- accept; ... finally (close conn) seems liable to leak the conn if an async exception is thrown immediately after the connection was accepted
There is two points where socket may leak: after accepting but
before spawning the worker thread; and after spawning it but before
establishing exception handler via `finally`.
Accept incoming con...
Based on my previous question I'd like to ask if there's any way to kill all user created threads in a GHCi session?
The reason for this is that when a function exits in GHCi the threads that it s...
How do you ensure a socket get closed in the event of an exception while retaining the ability to kill the thread that is waiting for connections on that socket?
I can only think of solutions that provide one or the other, not both:
bracket accept close ...
to guarantee cleanup masks async exceptions and prevents another thread from killing itconn <- accept; ... finally (close conn)
seems liable to leak theconn
if an async exception is thrown immediately after the connection was acceptedA while back, the websockets library switched from option 2 to 1 https://github.com/jaspervdj/websockets/commit/a43a16c6fbc0d624db4317cee2dbf8124d047490 which makes me think there's no way to get both.
It looks like warp also uses option 1 https://github.com/yesodweb/wai/blob/d57699d6efc155f919b0760806535ac589f8db23/warp/Network/Wai/Handler/Warp/Run.hs#L312
Is there a "safe"
accept
that atomically registers a cleanup handler while also allowing async exceptions?@chessai do finalizers of
ForeignPtr
s get called when being interrupted by asynchronous exception?To answer my own question, it seems like they're not guaranteed to be called at all: https://hackage.haskell.org/package/base-4.14.0.0/docs/Foreign-Concurrent.html#v:newForeignPtr
As an aside, ~4 of us spent 30+ minutes trying to figure out if GHCi can be told to kill all running threads on reload (I was running this server in the context of ghcid), and we pretty much concluded that it's impossible. See https://stackoverflow.com/questions/24999636/is-there-a-way-to-kill-all-forked-threads-in-a-ghci-session-without-restarting-i
heh, I was wondering the same thing this week, after moving a web server into a separate thread