Socket cleanup - Haskell

Welcome to the Functional Programming Zulip Chat Archive. You can join the chat here.

Chris Wendt

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

A 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?

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...
Haskell Web Application Interface. Contribute to yesodweb/wai development by creating an account on GitHub.
TheMatten

@chessai do finalizers of ForeignPtrs get called when being interrupted by asynchronous exception?

TheMatten

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

Chris Wendt

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

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...
Torsten Schmits

heh, I was wondering the same thing this week, after moving a web server into a separate thread