internal async Task WriteAsync(TorrentManager manager, long offset, byte[] buffer, int count) { Interlocked.Add(ref bufferedWriteBytes, count); await IOLoop; try { if (WriteLimiter.TryProcess(count)) { Write(manager, offset, buffer, count); } else { var tcs = new TaskCompletionSource <bool>(); bufferedWrites.Enqueue(new BufferedIO(manager, offset, buffer, count, tcs)); await tcs.Task; } } catch (Exception ex) { SetError(manager, Reason.WriteFailure, ex); } Interlocked.Add(ref bufferedWriteBytes, -count); }
public async Task <bool> ReadAsync(TorrentManager manager, long offset, byte [] buffer, int count) { await IOLoop; try { if (ReadLimiter.TryProcess(count)) { return(Read(manager, offset, buffer, count)); } else { var tcs = new TaskCompletionSource <bool>(); bufferedReads.Enqueue(new BufferedIO(manager, offset, buffer, count, tcs)); return(await tcs.Task); } } catch (Exception ex) { SetError(manager, Reason.ReadFailure, ex); return(false); } }
internal DiskManager(ClientEngine engine, PieceWriter writer) { this.bufferedReads = new Queue <BufferedIO>(); this.bufferedWrites = new Queue <BufferedIO>(); this.cache = new Cache <BufferedIO>(true).Synchronize(); this.engine = engine; this.readLimiter = new RateLimiter(); this.readMonitor = new SpeedMonitor(); this.writeMonitor = new SpeedMonitor(); this.writeLimiter = new RateLimiter(); this.writer = writer; LoopTask = delegate { if (disposed) { return; } while (this.bufferedWrites.Count > 0 && writeLimiter.TryProcess(bufferedWrites.Peek().buffer.Length / 2048)) { BufferedIO write; lock (bufferLock) write = this.bufferedWrites.Dequeue(); try { PerformWrite(write); cache.Enqueue(write); } catch (Exception ex) { //if (write.Manager != null) // SetError(write.Manager, Reason.WriteFailure, ex); } } while (this.bufferedReads.Count > 0 && readLimiter.TryProcess(bufferedReads.Peek().Count / 2048)) { BufferedIO read; lock (bufferLock) read = this.bufferedReads.Dequeue(); try { PerformRead(read); cache.Enqueue(read); } catch (Exception ex) { if (read.Manager != null) { SetError(read.Manager, Reason.ReadFailure, ex); } } } }; IOLoop.QueueTimeout(TimeSpan.FromSeconds(1), delegate { if (disposed) { return(false); } readMonitor.Tick(); writeMonitor.Tick(); LoopTask(); return(true); }); }
internal DiskManager(ClientEngine engine, PieceWriter writer) { this.bufferedReads = new Queue<BufferedIO>(); this.bufferedWrites = new Queue<BufferedIO>(); this.cache = new Cache<BufferedIO>(true).Synchronize (); this.engine = engine; this.readLimiter = new RateLimiter(); this.readMonitor = new SpeedMonitor(); this.writeMonitor = new SpeedMonitor(); this.writeLimiter = new RateLimiter(); this.writer = writer; LoopTask = delegate { if (disposed) return; while (this.bufferedWrites.Count > 0 && writeLimiter.TryProcess(bufferedWrites.Peek ().buffer.Length / 2048)) { BufferedIO write; lock (bufferLock) write = this.bufferedWrites.Dequeue(); try { PerformWrite(write); cache.Enqueue (write); } catch (Exception ex) { if (write.Manager != null) SetError(write.Manager, Reason.WriteFailure, ex); } } while (this.bufferedReads.Count > 0 && readLimiter.TryProcess(bufferedReads.Peek().Count / 2048)) { BufferedIO read; lock(bufferLock) read = this.bufferedReads.Dequeue(); try { PerformRead(read); cache.Enqueue (read); } catch (Exception ex) { if(read.Manager != null) SetError(read.Manager, Reason.ReadFailure, ex); } } }; IOLoop.QueueTimeout(TimeSpan.FromSeconds(1), delegate { if (disposed) return false; readMonitor.Tick(); writeMonitor.Tick(); LoopTask(); return true; }); }