public ClientEngine(EngineSettings settings, PeerListener listener, PieceWriter.PieceWriter writer) { Check.Settings(settings); Check.Listener(listener); Check.Writer(writer); Listener = listener; Settings = settings; ConnectionManager = new ConnectionManager(this); RegisterDht(new NullDhtEngine()); DiskManager = new DiskManager(this, writer); _listenManager = new ListenManager(this); MainLoop.QueueTimeout(TimeSpan.FromMilliseconds(TickLength), delegate { if (IsRunning && !Disposed) { LogicTick(); } return(!Disposed); }); _torrents = new List <TorrentManager>(); _torrentsReadonly = new ReadOnlyCollection <TorrentManager>(_torrents); CreateRateLimiters(); PeerId = GeneratePeerId(); _localPeerListener = new LocalPeerListener(this); _localPeerManager = new LocalPeerManager(); LocalPeerSearchEnabled = SupportsLocalPeerDiscovery; _listenManager.Register(listener); // This means we created the listener in the constructor if (listener.Endpoint.Port == 0) { listener.ChangeEndpoint(new IPEndPoint(IPAddress.Any, settings.ListenPort)); } }
internal DiskManager(ClientEngine engine, PieceWriter.PieceWriter writer) { _bufferedReads = new Queue <BufferedIO>(); _bufferedWrites = new Queue <BufferedIO>(); _cache = new Cache <BufferedIO>(true).Synchronize(); _engine = engine; ReadLimiter = new RateLimiter(); _readMonitor = new SpeedMonitor(); _writeMonitor = new SpeedMonitor(); WriteLimiter = new RateLimiter(); Writer = writer; _loopTask = delegate { if (Disposed) { return; } while (this._bufferedWrites.Count > 0 && WriteLimiter.TryProcess(_bufferedWrites.Peek().InternalBuffer.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); }); }