retry bind

This is a workaround for bind failing with EINVAL sometimes on OSX.
I don't know why; EVINAL should mean the socket is already bound to an
address, but this is with a new socket.
This commit is contained in:
Joey Hess 2012-09-27 12:22:50 -04:00 committed by Joey Hess
parent 1a3d772c73
commit fe3009d83b

View file

@ -80,7 +80,14 @@ localSocket = do
{ addrFlags = [AI_ADDRCONFIG]
, addrSocketType = Stream
}
go addr = bracketOnError (open addr) close (use addr)
{- Repeated attempts because bind sometimes fails for an
- unknown reason on OSX. -}
go addr = go' 100 addr
go' :: Int -> AddrInfo -> IO Socket
go' 0 _ = error "unable to bind to local socket"
go' n addr = do
r <- tryIO $ bracketOnError (open addr) close (use addr)
either (const $ go' (pred n) addr) return r
open addr = socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr)
close = sClose
use addr sock = do