Esempio n. 1
0
        internal async void ReceiveMessagesAsync(IConnection connection, IEncryption decryptor, RateLimiterGroup downloadLimiter, ConnectionMonitor monitor, TorrentManager torrentManager, PeerId id)
        {
            await MainLoop.SwitchToThreadpool();

            ByteBufferPool.Releaser releaser = default;
            try {
                while (true)
                {
                    if (id.AmRequestingPiecesCount == 0 && releaser.Buffer != null)
                    {
                        releaser.Dispose();
                        releaser = NetworkIO.BufferPool.Rent(1, out ByteBuffer _);
                    }
                    else if (id.AmRequestingPiecesCount > 0 && releaser.Buffer == null)
                    {
                        releaser.Dispose();
                        releaser = NetworkIO.BufferPool.Rent(Piece.BlockSize, out ByteBuffer _);
                    }
                    PeerMessage message = await PeerIO.ReceiveMessageAsync(connection, decryptor, downloadLimiter, monitor, torrentManager.Monitor, torrentManager, releaser.Buffer).ConfigureAwait(false);

                    HandleReceivedMessage(id, torrentManager, message);
                }
            } catch {
                releaser.Dispose();
                await ClientEngine.MainLoop;
                CleanupSocket(torrentManager, id);
            }
        }
Esempio n. 2
0
        internal async void ReceiveMessagesAsync(IPeerConnection connection, IEncryption decryptor, RateLimiterGroup downloadLimiter, ConnectionMonitor monitor, TorrentManager torrentManager, PeerId id)
        {
            await MainLoop.SwitchToThreadpool();

            Memory <byte> currentBuffer = default;

            Memory <byte> smallBuffer = default;

            ByteBufferPool.Releaser smallReleaser = default;

            Memory <byte> largeBuffer = default;

            ByteBufferPool.Releaser largeReleaser = default;
            try {
                while (true)
                {
                    if (id.AmRequestingPiecesCount == 0)
                    {
                        if (!largeBuffer.IsEmpty)
                        {
                            largeReleaser.Dispose();
                            largeReleaser = default;
                            largeBuffer   = currentBuffer = default;
                        }
                        if (smallBuffer.IsEmpty)
                        {
                            smallReleaser = NetworkIO.BufferPool.Rent(ByteBufferPool.SmallMessageBufferSize, out smallBuffer);
                            currentBuffer = smallBuffer;
                        }
                    }
                    else
                    {
                        if (!smallBuffer.IsEmpty)
                        {
                            smallReleaser.Dispose();
                            smallReleaser = default;
                            smallBuffer   = currentBuffer = default;
                        }
                        if (largeBuffer.IsEmpty)
                        {
                            largeReleaser = NetworkIO.BufferPool.Rent(ByteBufferPool.LargeMessageBufferSize, out largeBuffer);
                            currentBuffer = largeBuffer;
                        }
                    }

                    (PeerMessage message, PeerMessage.Releaser releaser) = await PeerIO.ReceiveMessageAsync(connection, decryptor, downloadLimiter, monitor, torrentManager.Monitor, torrentManager, currentBuffer).ConfigureAwait(false);

                    HandleReceivedMessage(id, torrentManager, message, releaser);
                }
            } catch {
                await ClientEngine.MainLoop;
                CleanupSocket(torrentManager, id);
            } finally {
                smallReleaser.Dispose();
                largeReleaser.Dispose();
            }
        }
Esempio n. 3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="manager">The torrent which the peer is associated with.</param>
        /// <param name="id">The peer whose message queue you want to start processing</param>
        internal async void TryProcessQueue(TorrentManager manager, PeerId id)
        {
            if (!id.MessageQueue.BeginProcessing())
            {
                return;
            }

            await MainLoop.SwitchToThreadpool();

            ByteBufferPool.Releaser socketMemoryReleaser = default;
            Memory <byte>           socketMemory         = default;

            try {
                while (id.MessageQueue.TryDequeue(out PeerMessage? msg, out PeerMessage.Releaser msgReleaser))
                {
                    using var autorelease = msgReleaser;

                    if (socketMemory.IsEmpty || socketMemory.Length < msg.ByteLength)
                    {
                        socketMemoryReleaser.Dispose();
                        socketMemoryReleaser = NetworkIO.BufferPool.Rent(msg.ByteLength, out socketMemory);
                    }

                    var buffer = socketMemory.Slice(0, msg.ByteLength);
                    if (msg is PieceMessage pm)
                    {
                        pm.SetData((default, buffer.Slice(buffer.Length - pm.RequestLength)));
Esempio n. 4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="manager">The torrent which the peer is associated with.</param>
        /// <param name="id">The peer whose message queue you want to start processing</param>
        internal async void TryProcessQueue(TorrentManager manager, PeerId id)
        {
            if (!id.MessageQueue.BeginProcessing())
            {
                return;
            }

            await MainLoop.SwitchToThreadpool();

            ByteBufferPool.Releaser messageBuffer = default;
            ByteBufferPool.Releaser pieceBuffer   = default;
            PeerMessage             msg;

            try {
                while ((msg = id.MessageQueue.TryDequeue()) != null)
                {
                    var msgLength = msg.ByteLength;

                    if (msg is PieceMessage pm)
                    {
                        if (pieceBuffer.Buffer == null)
                        {
                            pieceBuffer = DiskManager.BufferPool.Rent(msgLength, out ByteBuffer _);
                        }
                        pm.DataReleaser = pieceBuffer;
                        try {
                            await DiskManager.ReadAsync(manager, pm.StartOffset + ((long)pm.PieceIndex * manager.Torrent.PieceLength), pm.Data, pm.RequestLength).ConfigureAwait(false);
                        } catch (Exception ex) {
                            await ClientEngine.MainLoop;
                            manager.TrySetError(Reason.ReadFailure, ex);
                            return;
                        }
                        System.Threading.Interlocked.Increment(ref id.piecesSent);
                    }
                    else
                    {
                        pieceBuffer.Dispose();
                    }

                    if (messageBuffer.Buffer == null || messageBuffer.Buffer.Data.Length < msg.ByteLength)
                    {
                        messageBuffer.Dispose();
                        messageBuffer = NetworkIO.BufferPool.Rent(msgLength, out ByteBuffer _);
                    }
                    await PeerIO.SendMessageAsync(id.Connection, id.Encryptor, msg, manager.UploadLimiters, id.Monitor, manager.Monitor, messageBuffer.Buffer).ConfigureAwait(false);

                    if (msg is PieceMessage)
                    {
                        System.Threading.Interlocked.Decrement(ref id.isRequestingPiecesCount);
                    }

                    id.LastMessageSent.Restart();
                }
            } catch {
                await ClientEngine.MainLoop;
                CleanupSocket(manager, id);
            } finally {
                messageBuffer.Dispose();
                pieceBuffer.Dispose();
            }
        }