summaryrefslogtreecommitdiff
path: root/Presence/SendMessage.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Presence/SendMessage.hs')
-rw-r--r--Presence/SendMessage.hs17
1 files changed, 11 insertions, 6 deletions
diff --git a/Presence/SendMessage.hs b/Presence/SendMessage.hs
index 6e8ea2b9..d1db7a4f 100644
--- a/Presence/SendMessage.hs
+++ b/Presence/SendMessage.hs
@@ -1,8 +1,10 @@
1{-# LANGUAGE CPP #-} 1{-# LANGUAGE CPP #-}
2{-# LANGUAGE TypeFamilies #-} 2{-# LANGUAGE TypeFamilies #-}
3{-# LANGUAGE FlexibleContexts #-}
3module SendMessage 4module SendMessage
4 ( sendMessage 5 ( sendMessage
5 , CommandCache(..) 6 , CommandCache(..)
7 , ThreadChannelCommand(..)
6 , newOutgoingConnections 8 , newOutgoingConnections
7 , OutgoingConnections 9 , OutgoingConnections
8 ) where 10 ) where
@@ -47,7 +49,7 @@ import Network.Socket
47import XMPPTypes (Peer(..),discardPort,peerAddr,withPort,socketFamily) 49import XMPPTypes (Peer(..),discardPort,peerAddr,withPort,socketFamily)
48import SocketLike 50import SocketLike
49import ServerC (packetSink) 51import ServerC (packetSink)
50import ControlMaybe (handleIO,handleIO_) 52import ControlMaybe
51import Data.Conduit (Sink,Source) 53import Data.Conduit (Sink,Source)
52import qualified Data.ByteString as S (ByteString) 54import qualified Data.ByteString as S (ByteString)
53import XMLToByteStrings 55import XMLToByteStrings
@@ -64,11 +66,12 @@ modifyIORef' ref f = do
64 66
65class CommandCache cache where 67class CommandCache cache where
66 type CacheableCommand cache 68 type CacheableCommand cache
67
68 emptyCache :: cache 69 emptyCache :: cache
69
70 updateCache :: CacheableCommand cache -> cache -> cache 70 updateCache :: CacheableCommand cache -> cache -> cache
71 71
72class ThreadChannelCommand cmd where
73 isQuitCommand :: cmd -> Bool
74
72 75
73data OutgoingConnections cache = 76data OutgoingConnections cache =
74 OutgoingConnections (TVar (Map Peer (TChan (CacheableCommand cache), ThreadId))) 77 OutgoingConnections (TVar (Map Peer (TChan (CacheableCommand cache), ThreadId)))
@@ -91,7 +94,7 @@ newOutgoingConnections interpretCommands = do
91 94
92 95
93sendMessage 96sendMessage
94 :: CommandCache a => 97 :: (CommandCache a, ThreadChannelCommand (CacheableCommand a)) =>
95 OutgoingConnections a -> CacheableCommand a -> Peer -> IO () 98 OutgoingConnections a -> CacheableCommand a -> Peer -> IO ()
96sendMessage (OutgoingConnections cons interpretCommands) msg peer0 = do 99sendMessage (OutgoingConnections cons interpretCommands) msg peer0 = do
97 let peer = discardPort peer0 100 let peer = discardPort peer0
@@ -136,14 +139,16 @@ connect_to_server chan peer toPeer = (>> return ()) . runMaybeT $ do
136 fix $ \sendmsgs -> do 139 fix $ \sendmsgs -> do
137 connected <- liftIO . async $ connect' (peerAddr peer) port 140 connected <- liftIO . async $ connect' (peerAddr peer) port
138 141
139 sock <- MaybeT . fix $ \loop -> do 142 msock <- MaybeT . fix $ \loop -> do
140 e <- atomically $ orElse 143 e <- atomically $ orElse
141 (fmap Right $ waitSTM connected) 144 (fmap Right $ waitSTM connected)
142 (fmap Left $ readTChan chan) 145 (fmap Left $ readTChan chan)
143 case e of 146 case e of
147 Left cmd | isQuitCommand cmd -> return Nothing
144 Left cmd -> cacheCmd cmd cached >> loop 148 Left cmd -> cacheCmd cmd cached >> loop
145 Right sock -> return sock 149 Right sock -> return (Just sock)
146 150
151 withJust msock $ \sock -> do
147 retry <- do 152 retry <- do
148 (cache,snk) <- liftIO $ do 153 (cache,snk) <- liftIO $ do
149 h <- socketToHandle sock ReadWriteMode 154 h <- socketToHandle sock ReadWriteMode