Example #1
0
        async void WritePieceAsync (PieceMessage message, Piece piece)
        {
            long offset = (long) message.PieceIndex * Manager.Torrent.PieceLength + message.StartOffset;

            try {
                await DiskManager.WriteAsync (Manager.Torrent, offset, message.Data, message.RequestLength);
                if (Cancellation.IsCancellationRequested)
                    return;
            } catch (Exception ex) {
                Manager.TrySetError (Reason.WriteFailure, ex);
                return;
            } finally {
                ClientEngine.BufferPool.Return (message.Data);
            }

            piece.TotalWritten++;

            // If we haven't received all the pieces to disk, there's no point in hash checking
            if (!piece.AllBlocksWritten)
                return;

            // Hashcheck the piece as we now have all the blocks.
            byte[] hash;
            try {
                hash = await DiskManager.GetHashAsync (Manager.Torrent, piece.Index);
                if (Cancellation.IsCancellationRequested)
                    return;
            } catch (Exception ex) {
                Manager.TrySetError (Reason.ReadFailure, ex);
                return;
            }

            bool result = hash != null && Manager.Torrent.Pieces.IsValid (hash, piece.Index);
            Manager.OnPieceHashed (piece.Index, result, 1, 1);
            Manager.PieceManager.PendingHashCheckPieces[piece.Index] = false;
            if (!result)
                Manager.HashFails++;

            for (int i = 0; i < piece.Blocks.Length; i++)
                if (piece.Blocks[i].RequestedOff != null)
                    peers.Add ((PeerId) piece.Blocks[i].RequestedOff);

            foreach (PeerId peer in peers) {
                peer.Peer.HashedPiece (result);
                if (peer.Peer.TotalHashFails == 5)
                    ConnectionManager.CleanupSocket (Manager, peer);
            }
            peers.Clear ();

            // If the piece was successfully hashed, enqueue a new "have" message to be sent out
            if (result)
                Manager.finishedPieces.Enqueue (new HaveMessage (piece.Index));
        }