diff options
author | Joey Hess <joey@kitenet.net> | 2012-10-30 15:39:15 -0400 |
---|---|---|
committer | Joey Hess <joey@kitenet.net> | 2012-10-30 15:39:15 -0400 |
commit | 07cd1b2b40735d460c8225762fcf3992b9886c60 (patch) | |
tree | c08c38417dfd9cba94ac56e212fa9d5864927ac0 /Assistant/TransferSlots.hs | |
parent | bab7e83221468905b76e28bb123ebe26e146b97b (diff) |
pushed Assistant monad down into DaemonStatus code
Currently have three old versions of functions that more reworking is
needed to remove: getDaemonStatusOld, modifyDaemonStatusOld_, and
modifyDaemonStatusOld
Diffstat (limited to 'Assistant/TransferSlots.hs')
-rw-r--r-- | Assistant/TransferSlots.hs | 46 |
1 files changed, 25 insertions, 21 deletions
diff --git a/Assistant/TransferSlots.hs b/Assistant/TransferSlots.hs index 1963252e0..8afd23a12 100644 --- a/Assistant/TransferSlots.hs +++ b/Assistant/TransferSlots.hs @@ -17,20 +17,22 @@ import qualified Control.Exception as E import Control.Concurrent import qualified Control.Concurrent.MSemN as MSemN +type TransferGenerator = Assistant (Maybe (Transfer, TransferInfo, IO ())) + {- Waits until a transfer slot becomes available, then runs a - TransferGenerator, and then runs the transfer action in its own thread. -} -inTransferSlot :: TransferSlotRunner -inTransferSlot dstatus s gen = do - MSemN.wait s 1 - runTransferThread dstatus s =<< gen +inTransferSlot :: TransferGenerator -> Assistant () +inTransferSlot gen = do + flip MSemN.wait 1 <<~ transferSlots + runTransferThread =<< gen {- Runs a TransferGenerator, and its transfer action, - without waiting for a slot to become available. -} -inImmediateTransferSlot :: TransferSlotRunner -inImmediateTransferSlot dstatus s gen = do - MSemN.signal s (-1) - runTransferThread dstatus s =<< gen +inImmediateTransferSlot :: TransferGenerator -> Assistant () +inImmediateTransferSlot gen = do + flip MSemN.signal (-1) <<~ transferSlots + runTransferThread =<< gen {- Runs a transfer action, in an already allocated transfer slot. - Once it finishes, frees the transfer slot. @@ -42,24 +44,26 @@ inImmediateTransferSlot dstatus s gen = do - then pausing the thread until a ResumeTransfer exception is raised, - then rerunning the action. -} -runTransferThread :: DaemonStatusHandle -> TransferSlots -> Maybe (Transfer, TransferInfo, IO ()) -> IO () -runTransferThread _ s Nothing = MSemN.signal s 1 -runTransferThread dstatus s (Just (t, info, a)) = do - tid <- forkIO go - updateTransferInfo dstatus t $ info { transferTid = Just tid } +runTransferThread :: Maybe (Transfer, TransferInfo, IO ()) -> Assistant () +runTransferThread Nothing = flip MSemN.signal 1 <<~ transferSlots +runTransferThread (Just (t, info, a)) = do + d <- getAssistant id + tid <- liftIO $ forkIO $ go d + updateTransferInfo t $ info { transferTid = Just tid } where - go = catchPauseResume a - pause = catchPauseResume $ runEvery (Seconds 86400) noop + go d = catchPauseResume d a + pause d = catchPauseResume d $ runEvery (Seconds 86400) noop {- Note: This must use E.try, rather than E.catch. - When E.catch is used, and has called go in its exception - handler, Control.Concurrent.throwTo will block sometimes - when signaling. Using E.try avoids the problem. -} - catchPauseResume a' = do + catchPauseResume d a' = do r <- E.try a' :: IO (Either E.SomeException ()) case r of Left e -> case E.fromException e of - Just PauseTransfer -> pause - Just ResumeTransfer -> go - _ -> done - _ -> done - done = MSemN.signal s 1 + Just PauseTransfer -> pause d + Just ResumeTransfer -> go d + _ -> done d + _ -> done d + done d = flip runAssistant d $ + flip MSemN.signal 1 <<~ transferSlots |