From abb264a31187ae60711a81285512497d40c73364 Mon Sep 17 00:00:00 2001 From: Jon Kristensen Date: Thu, 10 May 2012 16:55:53 +0200 Subject: [PATCH] minor formatting and documentation additions; changed Session field order --- src/Network/XMPP/Concurrent/Monad.hs | 2 +- src/Network/XMPP/Concurrent/Threads.hs | 9 +++- src/Network/XMPP/Concurrent/Types.hs | 72 +++++++++++++------------- 3 files changed, 45 insertions(+), 38 deletions(-) diff --git a/src/Network/XMPP/Concurrent/Monad.hs b/src/Network/XMPP/Concurrent/Monad.hs index d89d51e..d894ad4 100644 --- a/src/Network/XMPP/Concurrent/Monad.hs +++ b/src/Network/XMPP/Concurrent/Monad.hs @@ -170,7 +170,7 @@ withConnection a = do write <- asks writeRef wait <- liftIO $ newEmptyTMVarIO liftIO . Ex.mask_ $ do - -- Kills the reader until the lock (wait) is released (set to `()'). + -- Suspends the reader until the lock (wait) is released (set to `()'). throwTo readerId $ Interrupt wait -- We acquire the write and stateRef locks, to make sure that this is -- the only thread that can write to the stream and to perform a diff --git a/src/Network/XMPP/Concurrent/Threads.hs b/src/Network/XMPP/Concurrent/Threads.hs index 654e94e..d5c2e0e 100644 --- a/src/Network/XMPP/Concurrent/Threads.hs +++ b/src/Network/XMPP/Concurrent/Threads.hs @@ -181,6 +181,11 @@ startThreads = do _ <- atomically $ takeTMVar writeLock -- Should we put it back? _ <- forM threads killThread return () + zeroEventHandlers :: EventHandlers + zeroEventHandlers = EventHandlers + { sessionEndHandler = return () + , connectionClosedHandler = \_ -> return () + } -- | Creates and initializes a new XMPP session. newSession :: IO Session @@ -194,10 +199,10 @@ newSession = do writeTVar idRef (curId + 1 :: Integer) return . read. show $ curId return $ Session - workermCh - workerpCh mC pC + workermCh + workerpCh outC hand writeR diff --git a/src/Network/XMPP/Concurrent/Types.hs b/src/Network/XMPP/Concurrent/Types.hs index c9e6cab..8089aed 100644 --- a/src/Network/XMPP/Concurrent/Types.hs +++ b/src/Network/XMPP/Concurrent/Types.hs @@ -14,49 +14,51 @@ import qualified Data.Map as Map import Data.Text(Text) import Data.Typeable - import Network.XMPP.Types - -type IQHandlers = (Map.Map (IQRequestType, Text) (TChan (IQRequest, TVar Bool)) +-- Map between the IQ request type and the "query" namespace pair, and the TChan +-- for the IQ request and "sent" boolean pair. +type IQHandlers = ( Map.Map (IQRequestType, Text) (TChan (IQRequest, TVar Bool)) , Map.Map StanzaId (TMVar IQResponse) ) +-- Handlers to be run when the XMPP session ends and when the XMPP connection is +-- closed. data EventHandlers = EventHandlers - { sessionEndHandler :: IO () - , connectionClosedHandler :: StreamError -> IO () - } - -zeroEventHandlers :: EventHandlers -zeroEventHandlers = EventHandlers - { sessionEndHandler = return () - , connectionClosedHandler = \_ -> return () - } - -data Session = Session { messagesRef :: IORef (Maybe ( TChan (Either - MessageError - Message - ))) - , presenceRef :: IORef (Maybe (TChan (Either - PresenceError Presence ))) - , mShadow :: TChan (Either MessageError - Message) - -- the original chan - , pShadow :: TChan (Either PresenceError - Presence) - -- the original chan - , outCh :: TChan Stanza - , iqHandlers :: TVar IQHandlers - , writeRef :: TMVar (BS.ByteString -> IO Bool ) - , readerThread :: ThreadId - , idGenerator :: IO StanzaId - , conStateRef :: TMVar XmppConnection - , eventHandlers :: TVar EventHandlers - , stopThreads :: IO () - } + { sessionEndHandler :: IO () + , connectionClosedHandler :: StreamError -> IO () + } + +-- The Session object is the XMPP (ReaderT) state. +data Session = Session + { -- The original master channels that the reader puts stanzas into. These + -- are cloned by @get{Message,Presence}Chan on demand when first used by + -- the thread and are stored in the {message,presence}Ref fields below. + mShadow :: TChan (Either MessageError Message) + , pShadow :: TChan (Either PresenceError Presence) + -- The cloned copies of the original/shadow channels. They are + -- thread-local (as opposed to the shadow channels) and contains all + -- stanzas received after the cloning of the shadow channels. + , messagesRef :: IORef (Maybe (TChan (Either MessageError Message))) + , presenceRef :: IORef (Maybe (TChan (Either PresenceError Presence))) + , outCh :: TChan Stanza + , iqHandlers :: TVar IQHandlers + -- Writing lock, so that only one thread could write to the stream at any + -- given time. + , writeRef :: TMVar (BS.ByteString -> IO Bool) + , readerThread :: ThreadId + , idGenerator :: IO StanzaId + -- Lock (used by withConnection) to make sure that a maximum of one + -- XMPPConMonad calculation is executed at any given time. + , conStateRef :: TMVar XmppConnection + , eventHandlers :: TVar EventHandlers + , stopThreads :: IO () + } +-- XMPP is a monad for concurrent XMPP usage. type XMPP a = ReaderT Session IO a +-- Interrupt is used to signal to the reader thread that it should stop. data Interrupt = Interrupt (TMVar ()) deriving Typeable instance Show Interrupt where show _ = "" -instance Ex.Exception Interrupt +instance Ex.Exception Interrupt \ No newline at end of file