2020-12-09 16:32:29 +00:00
|
|
|
{- A pool of "git-annex transfer" processes available for use
|
2020-12-07 16:50:48 +00:00
|
|
|
-
|
|
|
|
- Copyright 2013-2020 Joey Hess <id@joeyh.name>
|
|
|
|
-
|
|
|
|
- Licensed under the GNU AGPL version 3 or higher.
|
|
|
|
-}
|
|
|
|
|
|
|
|
module Types.TransferrerPool where
|
|
|
|
|
2020-12-07 17:08:59 +00:00
|
|
|
import Common
|
2020-12-07 16:50:48 +00:00
|
|
|
|
|
|
|
import Control.Concurrent.STM hiding (check)
|
|
|
|
|
2020-12-07 17:08:59 +00:00
|
|
|
type TransferrerPool = TVar [TransferrerPoolItem]
|
2020-12-07 16:50:48 +00:00
|
|
|
|
|
|
|
type CheckTransferrer = IO Bool
|
|
|
|
type MkCheckTransferrer = IO (IO Bool)
|
|
|
|
|
|
|
|
{- Each item in the pool may have a transferrer running, and has an
|
|
|
|
- IO action that can be used to check if it's still ok to use the
|
|
|
|
- transferrer. -}
|
|
|
|
data TransferrerPoolItem = TransferrerPoolItem (Maybe Transferrer) CheckTransferrer
|
|
|
|
|
|
|
|
data Transferrer = Transferrer
|
|
|
|
{ transferrerRead :: Handle
|
|
|
|
, transferrerWrite :: Handle
|
|
|
|
, transferrerHandle :: ProcessHandle
|
2020-12-11 19:28:58 +00:00
|
|
|
, transferrerShutdown :: IO ()
|
|
|
|
-- ^ Closes the FDs and waits for the process to exit.
|
|
|
|
-- Should be used when the transferrer is in between transfers,
|
|
|
|
-- as otherwise it may not shutdown promptly.
|
2020-12-07 16:50:48 +00:00
|
|
|
}
|
|
|
|
|
2020-12-07 17:08:59 +00:00
|
|
|
newTransferrerPool :: IO TransferrerPool
|
|
|
|
newTransferrerPool = newTVarIO []
|
2020-12-07 16:50:48 +00:00
|
|
|
|
|
|
|
popTransferrerPool :: TransferrerPool -> STM (Maybe TransferrerPoolItem, Int)
|
|
|
|
popTransferrerPool p = do
|
2020-12-07 17:08:59 +00:00
|
|
|
l <- readTVar p
|
2020-12-07 16:50:48 +00:00
|
|
|
case l of
|
|
|
|
[] -> return (Nothing, 0)
|
|
|
|
(i:is) -> do
|
2020-12-07 17:08:59 +00:00
|
|
|
writeTVar p is
|
2020-12-07 16:50:48 +00:00
|
|
|
return $ (Just i, length is)
|
|
|
|
|
|
|
|
pushTransferrerPool :: TransferrerPool -> TransferrerPoolItem -> STM ()
|
|
|
|
pushTransferrerPool p i = do
|
2020-12-07 17:08:59 +00:00
|
|
|
l <- readTVar p
|
2020-12-07 16:50:48 +00:00
|
|
|
let l' = i:l
|
2020-12-07 17:08:59 +00:00
|
|
|
writeTVar p l'
|
2020-12-07 16:50:48 +00:00
|
|
|
|
|
|
|
{- Note that making a CheckTransferrer may allocate resources,
|
|
|
|
- such as a NotificationHandle, so it's important that the returned
|
|
|
|
- TransferrerPoolItem is pushed into the pool, and not left to be
|
|
|
|
- garbage collected. -}
|
2020-12-07 17:08:59 +00:00
|
|
|
mkTransferrerPoolItem :: MkCheckTransferrer -> Transferrer -> IO TransferrerPoolItem
|
|
|
|
mkTransferrerPoolItem mkcheck t = do
|
2020-12-07 16:50:48 +00:00
|
|
|
check <- mkcheck
|
|
|
|
return $ TransferrerPoolItem (Just t) check
|