From 6cc097fa370954ebdf62af6a95ee4e21e2bda75d Mon Sep 17 00:00:00 2001 From: Philipp Balzarek Date: Fri, 27 Apr 2012 14:59:20 +0200 Subject: [PATCH] reader fixes: catch exceptions while blocking on readTMVar catch exceptiosn while waiting for semaphores --- src/Network/XMPP/Concurrent/Threads.hs | 38 ++++++++++++++++---------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/src/Network/XMPP/Concurrent/Threads.hs b/src/Network/XMPP/Concurrent/Threads.hs index 7a4309a..6a57dbb 100644 --- a/src/Network/XMPP/Concurrent/Threads.hs +++ b/src/Network/XMPP/Concurrent/Threads.hs @@ -29,6 +29,13 @@ import Text.XML.Stream.Elements import GHC.IO (unsafeUnmask) +-- While waiting for the first semaphore(s) to flip we might receive +-- another interrupt. When that happens we add it's semaphore to the +-- list and retry waiting +handleInterrupts ts = + Ex.catch (atomically $ forM ts takeTMVar) + ( \(Interrupt t) -> handleInterrupts (t:ts)) + readWorker :: TChan (Either MessageError Message) -> TChan (Either PresenceError Presence) -> TVar IQHandlers @@ -36,22 +43,25 @@ readWorker :: TChan (Either MessageError Message) -> IO () readWorker messageC presenceC handlers stateRef = Ex.mask_ . forever $ do - s <- liftIO . atomically $ takeTMVar stateRef - (sta', s') <- flip runStateT s $ Ex.catch ( do - -- we don't know whether pull will necessarily be interruptible - liftIO $ allowInterrupt - Just <$> pull - ) - (\(Interrupt t) -> do - liftIO . atomically $ - putTMVar stateRef s - liftIO . atomically $ takeTMVar t - return Nothing - ) + res <- liftIO $ Ex.catch ( + Ex.bracket + (atomically $ takeTMVar stateRef) + (atomically . putTMVar stateRef ) + (\s -> do + -- we don't know whether pull will + -- necessarily be interruptible + allowInterrupt + Just <$> runStateT pull s + ) + ) + (\(Interrupt t) -> do + handleInterrupts [t] + return Nothing + ) liftIO . atomically $ do - case sta' of + case res of Nothing -> return () - Just sta -> do + Just (sta, s') -> do putTMVar stateRef s' case sta of MessageS m -> do writeTChan messageC $ Right m