@@ -15,7 +15,7 @@ import Network.Socket
1515 ( AddrInfoFlag (AI_PASSIVE), HostName, ServiceName, Socket
1616 , SocketType (Stream), SocketOption (ReuseAddr)
1717 , accept, addrAddress, addrFlags, addrFamily, bindSocket, defaultProtocol
18− , getAddrInfo, listen, setSocketOption, socket, withSocketsDo )
18+ , getAddrInfo, listen, setSocketOption, socket, sClose, withSocketsDo )
1919import Safe
2020
2121import qualified Data.ByteString.Char8 as BS
@@ -23,7 +23,7 @@ import qualified Data.IntMap as IntMap
2323import qualified Network.Socket as N
2424import qualified Network.Socket.ByteString as NBS
2525
26−type Chans = MVar (Int, IntMap (Chan ByteString))
26+type Chans = MVar (Int, IntMap (Chan ByteString, MVar [Socket]))
2727type ChanId = Int
2828
2929-- | This deals with several different configuration properties:
@@ -51,14 +51,15 @@ mkTransport (TCPConfig _hints host service) = withSocketsDo $ do
5151 sock <- socket (addrFamily serverAddr) Stream defaultProtocol
5252 bindSocket sock (addrAddress serverAddr)
5353 listen sock 5
54− forkIO $ procConnections channels sock
54+ _ <- forkIO $ procConnections channels sock
5555
5656 return Transport
5757 { newConnectionWith = \_ -> do
5858 (chanId, chanMap) <- takeMVar channels
5959 chan <- newChan
60− putMVar channels (chanId + 1, IntMap.insert chanId chan chanMap)
61− return (mkSourceAddr host service chanId, mkTargetEnd chan)
60+ socks <- newMVar [sock]
61+ putMVar channels (chanId + 1, IntMap.insert chanId (chan, socks) chanMap)
62+ return (mkSourceAddr host service chanId, mkTargetEnd chan socks)
6263 , newMulticastWith = undefined
6364 , deserialize = \bs ->
6465 case readMay . BS.unpack $ bs of
@@ -85,14 +86,16 @@ mkTransport (TCPConfig _hints host service) = withSocketsDo $ do
8586 NBS.sendAll sock $ BS.pack . show $ chanId
8687 return $ SourceEnd
8788 { send = \bss -> NBS.sendMany sock bss
89+ , close = sClose sock
8890 }
8991
90− mkTargetEnd :: Chan ByteString -> TargetEnd
91− mkTargetEnd chan = TargetEnd
92+ mkTargetEnd :: Chan ByteString -> MVar [Socket] -> TargetEnd
93+ mkTargetEnd chan socks = TargetEnd
9294 { -- for now we will implement this as a Chan
9395 receive = do
9496 bs <- readChan chan
9597 return [bs]
98+ , closeAll = takeMVar socks >>= mapM_ sClose
9699 }
97100
98101 procConnections :: Chans -> Socket -> IO ()
@@ -107,9 +110,11 @@ mkTransport (TCPConfig _hints host service) = withSocketsDo $ do
107110 (_, chanMap) <- readMVar chans
108111 case IntMap.lookup chanId chanMap of
109112 Nothing -> error "procConnections: cannot find chanId"
110− Just chan -> forkIO $ do
111− unless (BS.null bs') $ writeChan chan bs'
112− procMessages chan clientSock
113+ Just (chan, socks) -> do
114+ modifyMVar_ socks (return . (clientSock :))
115+ forkIO $ do
116+ unless (BS.null bs') $ writeChan chan bs'
117+ procMessages chan clientSock
113118
114119 procMessages :: Chan ByteString -> Socket -> IO ()
115120 procMessages chan sock = forever $ do