conjure-0.1: src/Conjure/Logic/QueueManager.hs
-----------------------------------------------------------------------------
-- |
-- Module : Conjure.Logic.BlockSelector
-- Copyright : (c) Lemmih 2006
-- License : BSD-like
--
-- Maintainer : lemmih@gmail.com
-- Stability : experimental
-- Portability : non-portable (requires STM)
--
-- The queue manager runs in a thread for each connected peer. It's job it to
-- keep block queue full with the right blocks for every peer.
-----------------------------------------------------------------------------
module Conjure.Logic.QueueManager
( queueManager
) where
import Conjure.Types
import Conjure.Utils
import Conjure.Logic.BlockManagement
import Conjure.STM.PeerCtrl
import Conjure.Debug
import Control.Concurrent.STM
import Control.Monad (forever, when)
import qualified Data.Map as Map
queueManager :: ActiveTorrent -> ConnectedPeer -> IO ()
queueManager at peer
= forever $ atomically $
do stmTransactionName "QueueManager"
rc <- getRemoteChoke peer
si <- getLocalInterest peer
when (rc || not si) retry
limit <- readTVar (cpQueueLength peer)
blocks <- readTVar pendingBlocks
when (Map.size blocks >= limit) retry
mbBlock <- requestNewBlock at peer
case mbBlock of
Nothing -> do stmDebug "Out of blocks."
retry
Just block@(piece,offset,_)
-> let newBlocks = Map.insert (pIndex piece,offset) block blocks
in do --stmDebug $ "I want this block: " ++ show (pIndex piece, offset)
writeTVar pendingBlocks newBlocks
sendRequest peer block
where pendingBlocks = cpPendingBlocks peer