[Haskell-cafe] interrupting an accept()ing thread

Lukas Mai l.mai at web.de
Thu Jul 5 19:24:22 EDT 2007


Hello, cafe!

I have the following code (paraphrased):

...
forkIO spin
...
spin = do
    (t, _) <- accept s   -- (*)
    forkIO $ dealWith t  -- (**)
    spin

My problem is that I want to stop spin from another thread. The "obvious"
solution would be to throw it an exception. However, that leaks a socket
(t) if the exception arrives between (*) and (**). I could wrap the whole
thing in block, but from looking at the source of Network.Socket it seems
that accept itself is not exception safe; so no matter what I do, I can't
use asynchronous exceptions to make spin exit.

(Is this actually true? Should accept be fixed (along with a lot of other
library functions)?)

Another idea is to sClose s in another thread. This makes accept throw an
IO exception, which breaks the loop. Yay! But it introduces another race
condition: If a third thread creates a socket between sClose and accept,
the underlying file descriptor of s may get reused, leading to silently
wrong behavior because accept listens on the wrong socket now.

My question is: How can I use accept in a loop so that I can safely stop
it from another thread?


Lukas


More information about the Haskell-Cafe mailing list