예제 #1
0
        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);
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
        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);
            });
        }
예제 #4
0
        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;
            });
        }