|
52 | 52 | -- > , addrSocketType = Stream
|
53 | 53 | -- > }
|
54 | 54 | -- > head <$> getAddrInfo (Just hints) mhost (Just port)
|
55 |
| --- > open addr = do |
56 |
| --- > sock <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr) |
| 55 | +-- > open addr = E.bracketOnError (openSocket addr) close $ \sock -> do |
57 | 56 | -- > setSocketOption sock ReuseAddr 1
|
58 | 57 | -- > withFdSocket sock setCloseOnExecIfNeeded
|
59 | 58 | -- > bind sock $ addrAddress addr
|
60 | 59 | -- > listen sock 1024
|
61 | 60 | -- > return sock
|
62 |
| --- > loop sock = forever $ do |
63 |
| --- > (conn, _peer) <- accept sock |
64 |
| --- > void $ forkFinally (server conn) (const $ gracefulClose conn 5000) |
| 61 | +-- > loop sock = forever $ E.bracketOnError (accept sock) (close . fst) |
| 62 | +-- > $ \(conn, _peer) -> void $ |
| 63 | +-- > -- 'forkFinally' alone is unlikely to fail thus leaking @conn@, |
| 64 | +-- > -- but 'E.bracketOnError' above will be necessary if some |
| 65 | +-- > -- non-atomic setups (e.g. spawning a subprocess to handle |
| 66 | +-- > -- @conn@) before proper cleanup of @conn@ is your case |
| 67 | +-- > forkFinally (server conn) (const $ gracefulClose conn 5000) |
65 | 68 | --
|
66 | 69 | -- > {-# LANGUAGE OverloadedStrings #-}
|
67 | 70 | -- > -- Echo client program
|
|
88 | 91 | -- > resolve = do
|
89 | 92 | -- > let hints = defaultHints { addrSocketType = Stream }
|
90 | 93 | -- > head <$> getAddrInfo (Just hints) (Just host) (Just port)
|
91 |
| --- > open addr = do |
92 |
| --- > sock <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr) |
| 94 | +-- > open addr = E.bracketOnError (openSocket addr) close $ \sock -> do |
93 | 95 | -- > connect sock $ addrAddress addr
|
94 | 96 | -- > return sock
|
95 | 97 | --
|
|
0 commit comments