Browse Source

Add conection state to connection object, rename some types

rename XMPPConState to XmppConnection
rename xmppZeroCon to xmppNoConnection
add XmppConnectionState
remove sHaveTLS from XmppConnection
add (sConnectionState :: XmppConnectionState) to XmppConnection
master
Philipp Balzarek 14 years ago
parent
commit
45edfcc56f
  1. 3
      src/Network/XMPP/Concurrent/Monad.hs
  2. 6
      src/Network/XMPP/Concurrent/Threads.hs
  3. 2
      src/Network/XMPP/Concurrent/Types.hs
  4. 38
      src/Network/XMPP/Monad.hs
  5. 2
      src/Network/XMPP/TLS.hs
  6. 26
      src/Network/XMPP/Types.hs

3
src/Network/XMPP/Concurrent/Monad.hs

@ -152,8 +152,7 @@ waitForPresence f = do
-- Reader and writer workers will be temporarily stopped -- Reader and writer workers will be temporarily stopped
-- and resumed with the new session details once the action returns. -- and resumed with the new session details once the action returns.
-- The Action will run in the calling thread/ -- The Action will run in the calling thread/
-- NB: This will /not/ catch any exceptions. If you action dies, deadlocks -- Any uncaught exceptions will be interpreted as connection failure
-- or otherwisely exits abnormaly the XMPP session will be dead.
withConnection :: XMPPConMonad a -> XMPP a withConnection :: XMPPConMonad a -> XMPP a
withConnection a = do withConnection a = do
readerId <- asks readerThread readerId <- asks readerThread

6
src/Network/XMPP/Concurrent/Threads.hs

@ -40,7 +40,7 @@ handleInterrupts ts =
readWorker :: TChan (Either MessageError Message) readWorker :: TChan (Either MessageError Message)
-> TChan (Either PresenceError Presence) -> TChan (Either PresenceError Presence)
-> TVar IQHandlers -> TVar IQHandlers
-> TMVar XMPPConState -> TMVar XmppConnection
-> IO () -> IO ()
readWorker messageC presenceC handlers stateRef = readWorker messageC presenceC handlers stateRef =
Ex.mask_ . forever $ do Ex.mask_ . forever $ do
@ -131,7 +131,7 @@ startThreads
, TChan Stanza , TChan Stanza
, IO () , IO ()
, TMVar (BS.ByteString -> IO ()) , TMVar (BS.ByteString -> IO ())
, TMVar XMPPConState , TMVar XmppConnection
, ThreadId , ThreadId
, TVar EventHandlers , TVar EventHandlers
) )
@ -143,7 +143,7 @@ startThreads = do
outC <- newTChanIO outC <- newTChanIO
handlers <- newTVarIO ( Map.empty, Map.empty) handlers <- newTVarIO ( Map.empty, Map.empty)
eh <- newTVarIO zeroEventHandlers eh <- newTVarIO zeroEventHandlers
conS <- newTMVarIO xmppZeroConState conS <- newTMVarIO xmppNoConnection
lw <- forkIO $ writeWorker outC writeLock lw <- forkIO $ writeWorker outC writeLock
cp <- forkIO $ connPersist writeLock cp <- forkIO $ connPersist writeLock
rd <- forkIO $ readWorker messageC presenceC handlers conS rd <- forkIO $ readWorker messageC presenceC handlers conS

2
src/Network/XMPP/Concurrent/Types.hs

@ -50,7 +50,7 @@ data Session = Session { messagesRef :: IORef (Maybe ( TChan (Either
, writeRef :: TMVar (BS.ByteString -> IO () ) , writeRef :: TMVar (BS.ByteString -> IO () )
, readerThread :: ThreadId , readerThread :: ThreadId
, idGenerator :: IO StanzaId , idGenerator :: IO StanzaId
, conStateRef :: TMVar XMPPConState , conStateRef :: TMVar XmppConnection
, eventHandlers :: TVar EventHandlers , eventHandlers :: TVar EventHandlers
, stopThreads :: IO () , stopThreads :: IO ()
} }

38
src/Network/XMPP/Monad.hs

@ -8,7 +8,6 @@ import Control.Monad
import Control.Monad.IO.Class import Control.Monad.IO.Class
import Control.Monad.Trans.Class import Control.Monad.Trans.Class
--import Control.Monad.Trans.Resource --import Control.Monad.Trans.Resource
import Control.Concurrent
import qualified Control.Exception as Ex import qualified Control.Exception as Ex
import Control.Monad.State.Strict import Control.Monad.State.Strict
@ -69,38 +68,36 @@ pullStanza = do
xmppFromHandle :: Handle xmppFromHandle :: Handle
-> Text -> Text
-> Text
-> Maybe Text
-> XMPPConMonad a -> XMPPConMonad a
-> IO (a, XMPPConState) -> IO (a, XmppConnection)
xmppFromHandle handle hostname username res f = do xmppFromHandle handle hostname f = do
liftIO $ hSetBuffering handle NoBuffering liftIO $ hSetBuffering handle NoBuffering
let raw = sourceHandle handle let raw = sourceHandle handle
let src = raw $= XP.parseBytes def let src = raw $= XP.parseBytes def
let st = XMPPConState let st = XmppConnection
src src
(raw) (raw)
(BS.hPut handle) (BS.hPut handle)
(Just handle) (Just handle)
(SF Nothing [] []) (SF Nothing [] [])
False XmppConnectionPlain
(Just hostname) (Just hostname)
(Just username) Nothing
res Nothing
(hClose handle) (hClose handle)
runStateT f st runStateT f st
zeroSource :: Source IO output zeroSource :: Source IO output
zeroSource = liftIO . forever $ threadDelay 10000000 zeroSource = liftIO . Ex.throwIO $ XmppNoConnection
xmppZeroConState :: XMPPConState xmppNoConnection :: XmppConnection
xmppZeroConState = XMPPConState xmppNoConnection = XmppConnection
{ sConSrc = zeroSource { sConSrc = zeroSource
, sRawSrc = zeroSource , sRawSrc = zeroSource
, sConPushBS = (\_ -> return ()) , sConPushBS = \_ -> Ex.throwIO $ XmppNoConnection
, sConHandle = Nothing , sConHandle = Nothing
, sFeatures = SF Nothing [] [] , sFeatures = SF Nothing [] []
, sHaveTLS = False , sConnectionState = XmppConnectionClosed
, sHostname = Nothing , sHostname = Nothing
, sUsername = Nothing , sUsername = Nothing
, sResource = Nothing , sResource = Nothing
@ -116,29 +113,32 @@ xmppRawConnect host hostname = do
return con return con
let raw = sourceHandle con let raw = sourceHandle con
src <- liftIO . bufferSource $ raw $= XP.parseBytes def src <- liftIO . bufferSource $ raw $= XP.parseBytes def
let st = XMPPConState let st = XmppConnection
src src
(raw) (raw)
(BS.hPut con) (BS.hPut con)
(Just con) (Just con)
(SF Nothing [] []) (SF Nothing [] [])
False XmppConnectionPlain
(Just hostname) (Just hostname)
uname uname
Nothing Nothing
(hClose con) (hClose con)
put st put st
xmppNewSession :: XMPPConMonad a -> IO (a, XMPPConState) xmppNewSession :: XMPPConMonad a -> IO (a, XmppConnection)
xmppNewSession action = do xmppNewSession action = do
runStateT action xmppZeroConState runStateT action xmppNoConnection
xmppKillConnection :: XMPPConMonad () xmppKillConnection :: XMPPConMonad ()
xmppKillConnection = do xmppKillConnection = do
cc <- gets sCloseConnection cc <- gets sCloseConnection
void . liftIO $ (Ex.try cc :: IO (Either Ex.SomeException ())) void . liftIO $ (Ex.try cc :: IO (Either Ex.SomeException ()))
put xmppZeroConState put xmppNoConnection
xmppSendIQ' :: StanzaId -> Maybe JID -> IQRequestType
-> Maybe LangTag -> Element
-> XMPPConMonad (Either IQError IQResult)
xmppSendIQ' iqID to tp lang body = do xmppSendIQ' iqID to tp lang body = do
push . IQRequestS $ IQRequest iqID Nothing to lang tp body push . IQRequestS $ IQRequest iqID Nothing to lang tp body
res <- pullPickle $ xpEither xpIQError xpIQResult res <- pullPickle $ xpEither xpIQError xpIQResult

2
src/Network/XMPP/TLS.hs

@ -70,6 +70,6 @@ startTLS params = Ex.handle (return . Left . TLSError)
, sCloseConnection = TLS.bye ctx >> sCloseConnection x , sCloseConnection = TLS.bye ctx >> sCloseConnection x
}) })
either (lift . Ex.throwIO) return =<< lift xmppRestartStream either (lift . Ex.throwIO) return =<< lift xmppRestartStream
modify (\s -> s{sHaveTLS = True}) modify (\s -> s{sConnectionState = XmppConnectionSecured})
return () return ()

26
src/Network/XMPP/Types.hs

@ -38,7 +38,9 @@ module Network.XMPP.Types
, StreamError(..) , StreamError(..)
, Version(..) , Version(..)
, XMPPConMonad , XMPPConMonad
, XMPPConState(..) , XmppConnection(..)
, XmppConnectionState(..)
, XmppNoConnection(..)
, XMPPT(..) , XMPPT(..)
, XmppStreamError(..) , XmppStreamError(..)
, parseLangTag , parseLangTag
@ -704,13 +706,21 @@ data ServerFeatures = SF
, other :: [Element] , other :: [Element]
} deriving Show } deriving Show
data XMPPConState = XMPPConState data XmppConnectionState = XmppConnectionClosed -- ^ No connection at
-- this point
| XmppConnectionPlain -- ^ Connection
-- established, but
-- not secured
| XmppConnectionSecured -- ^ Connection
-- established and
-- secured via TLS
data XmppConnection = XmppConnection
{ sConSrc :: Source IO Event { sConSrc :: Source IO Event
, sRawSrc :: Source IO BS.ByteString , sRawSrc :: Source IO BS.ByteString
, sConPushBS :: BS.ByteString -> IO () , sConPushBS :: BS.ByteString -> IO ()
, sConHandle :: Maybe Handle , sConHandle :: Maybe Handle
, sFeatures :: ServerFeatures , sFeatures :: ServerFeatures
, sHaveTLS :: Bool , sConnectionState :: XmppConnectionState
, sHostname :: Maybe Text , sHostname :: Maybe Text
, sUsername :: Maybe Text , sUsername :: Maybe Text
, sResource :: Maybe Text , sResource :: Maybe Text
@ -723,14 +733,14 @@ data XMPPConState = XMPPConState
-- work with Pontarius. Pontarius clients needs to operate in this -- work with Pontarius. Pontarius clients needs to operate in this
-- context. -- context.
newtype XMPPT m a = XMPPT { runXMPPT :: StateT XMPPConState m a } deriving (Monad, MonadIO) newtype XMPPT m a = XMPPT { runXMPPT :: StateT XmppConnection m a } deriving (Monad, MonadIO)
type XMPPConMonad a = StateT XMPPConState IO a type XMPPConMonad a = StateT XmppConnection IO a
-- Make XMPPT derive the Monad and MonadIO instances. -- Make XMPPT derive the Monad and MonadIO instances.
deriving instance (Monad m, MonadIO m) => MonadState (XMPPConState) (XMPPT m) deriving instance (Monad m, MonadIO m) => MonadState (XmppConnection) (XMPPT m)
data XmppNoConnection = XmppNoConnection deriving (Show, Typeable)
instance Exception XmppNoConnection
-- We need a channel because multiple threads needs to append events,
-- and we need to wait for events when there are none.

Loading…
Cancel
Save