use System.Timeout

I'd forgotten this existed!
This commit is contained in:
Joey Hess 2012-11-14 11:53:23 -04:00
parent 481f32dfbc
commit 98d45cd383
2 changed files with 12 additions and 26 deletions

View file

@ -25,7 +25,6 @@ import qualified Git.Branch
import Locations.UserConfig import Locations.UserConfig
import qualified Types.Remote as Remote import qualified Types.Remote as Remote
import Utility.FileMode import Utility.FileMode
import Utility.ThreadScheduler
import Network.Protocol.XMPP import Network.Protocol.XMPP
import qualified Data.Text as T import qualified Data.Text as T
@ -33,6 +32,7 @@ import System.Posix.Env
import System.Posix.Types import System.Posix.Types
import System.Process (std_in, std_out, std_err) import System.Process (std_in, std_out, std_err)
import Control.Concurrent import Control.Concurrent
import System.Timeout
import qualified Data.ByteString as B import qualified Data.ByteString as B
import qualified Data.Map as M import qualified Data.Map as M
@ -119,16 +119,16 @@ xmppPush cid gitpush = runPush SendPack cid handleDeferred $ do
then liftIO $ killThread =<< myThreadId then liftIO $ killThread =<< myThreadId
else sendNetMessage $ Pushing cid $ SendPackOutput b else sendNetMessage $ Pushing cid $ SendPackOutput b
fromxmpp outh controlh = forever $ do fromxmpp outh controlh = forever $ do
m <- runTimeout xmppTimeout <~> waitNetPushMessage SendPack m <- timeout xmppTimeout <~> waitNetPushMessage SendPack
case m of case m of
(Right (Pushing _ (ReceivePackOutput b))) -> (Just (Pushing _ (ReceivePackOutput b))) ->
liftIO $ writeChunk outh b liftIO $ writeChunk outh b
(Right (Pushing _ (ReceivePackDone exitcode))) -> (Just (Pushing _ (ReceivePackDone exitcode))) ->
liftIO $ do liftIO $ do
hPrint controlh exitcode hPrint controlh exitcode
hFlush controlh hFlush controlh
(Right _) -> noop (Just _) -> noop
(Left _) -> do Nothing -> do
debug ["timeout waiting for git receive-pack output via XMPP"] debug ["timeout waiting for git receive-pack output via XMPP"]
-- Send a synthetic exit code to git-annex -- Send a synthetic exit code to git-annex
-- xmppgit, which will exit and cause git push -- xmppgit, which will exit and cause git push
@ -220,12 +220,12 @@ xmppReceivePack cid = runPush ReceivePack cid handleDeferred $ do
sendNetMessage $ Pushing cid $ ReceivePackOutput b sendNetMessage $ Pushing cid $ ReceivePackOutput b
relaytoxmpp outh relaytoxmpp outh
relayfromxmpp inh = forever $ do relayfromxmpp inh = forever $ do
m <- runTimeout xmppTimeout <~> waitNetPushMessage ReceivePack m <- timeout xmppTimeout <~> waitNetPushMessage ReceivePack
case m of case m of
(Right (Pushing _ (SendPackOutput b))) -> (Just (Pushing _ (SendPackOutput b))) ->
liftIO $ writeChunk inh b liftIO $ writeChunk inh b
(Right _) -> noop (Just _) -> noop
(Left _) -> do Nothing -> do
debug ["timeout waiting for git send-pack output via XMPP"] debug ["timeout waiting for git send-pack output via XMPP"]
-- closing the handle will make -- closing the handle will make
-- git receive-pack exit -- git receive-pack exit
@ -291,5 +291,5 @@ chunkSize = 4096
- delayed for running until the timeout is reached, so it should not be - delayed for running until the timeout is reached, so it should not be
- excessive. - excessive.
-} -}
xmppTimeout :: Seconds xmppTimeout :: Int
xmppTimeout = Seconds 120 xmppTimeout = 120000000 -- 120 seconds

View file

@ -12,7 +12,6 @@ import Common
import Control.Concurrent import Control.Concurrent
import Control.Exception import Control.Exception
import Control.Concurrent.Async
import System.Posix.Terminal import System.Posix.Terminal
import System.Posix.Signals import System.Posix.Signals
@ -46,19 +45,6 @@ unboundDelay time = do
threadDelay $ fromInteger maxWait threadDelay $ fromInteger maxWait
when (maxWait /= time) $ unboundDelay (time - maxWait) when (maxWait /= time) $ unboundDelay (time - maxWait)
{- Runs an action until a timeout is reached. If it fails to complete in
- time, or throws an exception, returns a Left value.
-
- Note that if the action runs an unsafe foreign call, the signal to
- cancel it may not arrive until the call returns. -}
runTimeout :: Seconds -> IO a -> IO (Either SomeException a)
runTimeout secs a = do
runner <- async a
controller <- async $ do
threadDelaySeconds secs
cancel runner
cancel controller `after` waitCatch runner
{- Pauses the main thread, letting children run until program termination. -} {- Pauses the main thread, letting children run until program termination. -}
waitForTermination :: IO () waitForTermination :: IO ()
waitForTermination = do waitForTermination = do