summaryrefslogtreecommitdiff
path: root/src/Network/BitTorrent/Exchange/Session
diff options
context:
space:
mode:
Diffstat (limited to 'src/Network/BitTorrent/Exchange/Session')
-rw-r--r--src/Network/BitTorrent/Exchange/Session/Metadata.hs28
1 files changed, 16 insertions, 12 deletions
diff --git a/src/Network/BitTorrent/Exchange/Session/Metadata.hs b/src/Network/BitTorrent/Exchange/Session/Metadata.hs
index 5d72172a..02c2269f 100644
--- a/src/Network/BitTorrent/Exchange/Session/Metadata.hs
+++ b/src/Network/BitTorrent/Exchange/Session/Metadata.hs
@@ -17,6 +17,7 @@ module Network.BitTorrent.Exchange.Session.Metadata
17 17
18import Control.Concurrent 18import Control.Concurrent
19import Control.Lens 19import Control.Lens
20import Control.Monad.Reader
20import Control.Monad.State 21import Control.Monad.State
21import Data.ByteString as BS 22import Data.ByteString as BS
22import Data.ByteString.Lazy as BL 23import Data.ByteString.Lazy as BL
@@ -43,14 +44,15 @@ makeLenses ''Status
43nullStatus :: Int -> Status 44nullStatus :: Int -> Status
44nullStatus ps = Status [] (Block.empty ps) 45nullStatus ps = Status [] (Block.empty ps)
45 46
46type Updates a = State Status a 47type Updates = ReaderT (PeerAddr IP) (State Status)
47 48
48runUpdates :: MVar Status -> Updates a -> IO a 49runUpdates :: MVar Status -> PeerAddr IP -> Updates a -> IO a
49runUpdates v m = modifyMVar v (return . swap . runState m) 50runUpdates v a m = modifyMVar v (return . swap . runState (runReaderT m a))
50 51
51scheduleBlock :: PeerAddr IP -> Updates (Maybe PieceIx) 52scheduleBlock :: Updates (Maybe PieceIx)
52scheduleBlock addr = do 53scheduleBlock = do
53 bkt <- use bucket 54 addr <- ask
55 bkt <- use bucket
54 case spans metadataPieceSize bkt of 56 case spans metadataPieceSize bkt of
55 [] -> return Nothing 57 [] -> return Nothing
56 ((off, _ ) : _) -> do 58 ((off, _ ) : _) -> do
@@ -61,8 +63,10 @@ scheduleBlock addr = do
61cancelPending :: PieceIx -> Updates () 63cancelPending :: PieceIx -> Updates ()
62cancelPending pix = pending %= L.filter ((pix ==) . snd) 64cancelPending pix = pending %= L.filter ((pix ==) . snd)
63 65
64resetPending :: PeerAddr IP -> Updates () 66resetPending :: Updates ()
65resetPending addr = pending %= L.filter ((addr ==) . fst) 67resetPending = do
68 addr <- ask
69 pending %= L.filter ((addr ==) . fst)
66 70
67parseInfoDict :: BS.ByteString -> InfoHash -> Result InfoDict 71parseInfoDict :: BS.ByteString -> InfoHash -> Result InfoDict
68parseInfoDict chunk topic = 72parseInfoDict chunk topic =
@@ -73,10 +77,10 @@ parseInfoDict chunk topic =
73 Left err -> Left $ "unable to parse infodict " ++ err 77 Left err -> Left $ "unable to parse infodict " ++ err
74 78
75-- todo use incremental parsing to avoid BS.concat call 79-- todo use incremental parsing to avoid BS.concat call
76pushBlock :: PeerAddr IP -> Torrent.Piece BS.ByteString -> InfoHash 80pushBlock :: Torrent.Piece BS.ByteString -> InfoHash -> Updates (Maybe InfoDict)
77 -> Updates (Maybe InfoDict) 81pushBlock Torrent.Piece {..} topic = do
78pushBlock addr Torrent.Piece {..} topic = do 82 addr <- ask
79 p <- use pending 83 p <- use pending
80 when ((addr, pieceIndex) `L.notElem` p) $ error "not requested" 84 when ((addr, pieceIndex) `L.notElem` p) $ error "not requested"
81 cancelPending pieceIndex 85 cancelPending pieceIndex
82 86