internal void TryProcessAsyncReads()
{
foreach (var message in PieceReads)
Enqueue(message);
PieceReads.Clear();
return;
// We only allow 2 simultaenous PieceMessages in a peers send queue.
// This way if the peer requests 100 pieces, we don't bloat our memory
// usage unnecessarily. Once the first message is sent, we read data
// for the *next* message asynchronously and then add it to the queue.
// While this is happening, we send data from the second PieceMessage in
// the queue, thus the queue should rarely be empty.
int existingReads = 0;
if (currentlySendingMessage is PieceMessage)
existingReads++;
for (int i = 0; existingReads < 2 && i < sendQueue.Count; i++)
if (sendQueue[i] is PieceMessage)
existingReads++;
if (existingReads >= 2)
return;
PieceMessage m = null;
for (int i = 0; m == null && i < PieceReads.Count; i++)
if (PieceReads [i].Data == BufferManager.EmptyBuffer)
m = PieceReads[i];
if (m == null)
return;
long offset = (long)m.PieceIndex * torrentManager.Torrent.PieceLength + m.StartOffset;
ClientEngine.BufferManager.GetBuffer(ref m.Data, m.RequestLength);
engine.DiskManager.QueueRead(torrentManager, offset, m.Data, m.RequestLength, delegate {
ClientEngine.MainLoop.Queue(delegate {
if (!PieceReads.Contains(m))
ClientEngine.BufferManager.FreeBuffer(ref m.Data);
else
{
PieceReads.Remove(m);
Enqueue(m);
}
TryProcessAsyncReads();
});
});
}