Ejemplo n.º 1
0
 public void WaitAndRealese(PeerHandler handler, IResourcePool <PeerHandler> returnPool, int waitSeconds)
 {
     Task.Factory.StartNew(() => {
         PeerHandler h = handler;
         Thread.Sleep(waitSeconds);
         returnPool.Realese(h);
     });
 }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        /// <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();
        }
Ejemplo n.º 4
0
        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);
            });
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
0
        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);
        }
Ejemplo n.º 7
0
        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();
        }