public void WaitAndRealese(PeerHandler handler, IResourcePool <PeerHandler> returnPool, int waitSeconds) { Task.Factory.StartNew(() => { PeerHandler h = handler; Thread.Sleep(waitSeconds); returnPool.Realese(h); }); }
public void AwaitBitfield(PeerHandler handler, IResourcePool <PeerHandler> returnPool, int awaitSeconds, int triesCount = 1) { ManualResetEventSlim eventReset = new ManualResetEventSlim(); handler.OnBitfield += h => eventReset.Set(); AwaitHandler(eventReset, handler, returnPool, awaitSeconds, triesCount); }
/// <summary> /// Starts a listener that will restart as needed /// </summary> /// <param name="port">port to listen on</param> /// <param name="handler">default peer handler, must be thread safe</param> public PersistentListener(int port, PeerHandler handler) { DefaultPeerHandler = handler; Listen(port); WorkerThread = new Thread(new ThreadStart(DoWork)); WorkerThread.Start(); }
public void AwaitHandler(ManualResetEventSlim eventReset, PeerHandler handler, IResourcePool <PeerHandler> returnPool, int awaitSeconds, int triesCount = 1) { Task.Factory.StartNew(() => { PeerHandler h = handler; for (int i = 0; i < triesCount; i++) { if (eventReset.Wait(awaitSeconds * 1000)) { returnPool.Realese(h); return; } } returnPool.Dispose(h); }); }
public void AwaitUnchoke(PeerHandler handler, IResourcePool <PeerHandler> returnPool, int awaitSeconds, int triesCount = 1) { ManualResetEventSlim eventReset = new ManualResetEventSlim(); void OnPeerUnchoke(PeerHandler h) { eventReset.Set(); if (_rarestPieceRqStrat != null) { UpdatePiecesRarity(h.PiecesHave); } h.OnUnchoke -= OnPeerUnchoke; } handler.OnUnchoke += OnPeerUnchoke; AwaitHandler(eventReset, handler, returnPool, awaitSeconds, triesCount); }
public bool Write(PeerHandler from, byte[] msg, int pieceOffset, int msgOffset) { Debug.WriteLine("Writing block to piece #{0}. Piece offset = {1}, Msg offset = {2}", Index, pieceOffset, msgOffset); var blockIdx = pieceOffset / _blockLen; if (_blocks[blockIdx]) { Debug.WriteLine("Piece #{0} already contains block with offset {1}", Index, pieceOffset); return(false); } lock (_wirteLock) { _blocks.Set(blockIdx, true); } Buffer.BlockCopy(msg, msgOffset, Payload, pieceOffset, msg.Length - msgOffset); OnBlockDownload?.Invoke(from, this, pieceOffset, _blockLen); if (_blocks.AllTrue) { Debug.WriteLine("Blocks of piece #{0} are downloaded, validating...", Index); IsValid = true; //TODO: _client.ValidatePiece(this); if (IsValid) { Debug.WriteLine("Piece #{0} is valid ", Index); } else { _blocks.SetAll(false); Debug.WriteLine("Piece #{0} is not valid ", Index); } OnPieceDone?.Invoke(this); } return(true); }
private void StartRequesting() { CountdownEvent pendingPiecesCountDown = new CountdownEvent(1); Piece nextPiece = null; bool stopped = false; do { do { int next = RequestStrategy.Next(); if (next < 0) { break; } nextPiece = _client.GetPiece(next); Trace.WriteLine($"RequestManager: Next piece to request is # {next}"); if (nextPiece.IsValid) // Might be valid if it was fetched from external storage { Debug.WriteLine($"RequestManager: Fetched piece #{nextPiece.Index} from cache"); continue; } int start = 0, curBlockLen = _blockLen; pendingPiecesCountDown.AddCount(); nextPiece.OnPieceDone += (p) => { pendingPiecesCountDown.Signal(); }; do { PeerHandler handler = null; try { Debug.WriteLine($"RequestManager: Acquiring handler..."); handler = _exchange.Acquire(nextPiece.Index, _outCancelToken); Debug.WriteLine($"RequestManager: Handler acquired"); } catch (OperationCanceledException) { Trace.WriteLine($"RequestManager: Cancelled acquire, restarting..."); break; } // nothing in lower pools, wait and try to acquire handler once more if (handler == null) { Debug.WriteLine($"RequestManager: No handler in lower pools, waiting {WaitTimeoutForLowerPoolInMSec / 1000} secs and trying once more"); Thread.Sleep(WaitTimeoutForLowerPoolInMSec); continue; } curBlockLen = nextPiece.PieceLength - start < _blockLen ? nextPiece.PieceLength - start : curBlockLen; ThreadPool.QueueUserWorkItem((offsetsTupleObj) => { Tuple <Piece, int, int> offsetsTuple = (Tuple <Piece, int, int>)offsetsTupleObj; try { handler.RequestPiece(offsetsTuple.Item1, offsetsTuple.Item2, offsetsTuple.Item3, _outCancelToken); } catch (OperationCanceledException) { } finally { _exchange.Realese(handler); } }, new Tuple <Piece, int, int>(nextPiece, start, curBlockLen)); start += curBlockLen; // last block of piece, breaking if (curBlockLen < _blockLen) { break; } } while (start < nextPiece.PieceLength && !_outCancelToken.IsCancellationRequested); stopped = _myCancelTokenOwner.IsCancellationRequested || _outCancelToken.IsCancellationRequested; } while (!stopped); if (stopped) { break; } // Initial count pendingPiecesCountDown.Signal(); Trace.WriteLine($"PiecePicker: Finished requesting, pending pieces count {pendingPiecesCountDown.CurrentCount}"); if (pendingPiecesCountDown.Wait(WaitTimeoutForEndGamePiecesInMSec, _outCancelToken)) { break; } else { foreach (var uploader in _exchange.GetUploaders()) { uploader.CancelPendingOutboundRequests(); } pendingPiecesCountDown.Reset(); } } while (!stopped); _exchange.Stop(); Trace.WriteLine($"RequestManager: Finished requesting"); Finished?.Invoke(); }