Пример #1
0
  /**
   * Adds a new request to the outstanding requests list. Then send interested if we weren't. Then
   * send new requests if not choked. If nothing to request, send not interested if we were.
   *
   * <p>This is called from several places:
   *
   * <pre>
   *   By getOustandingRequest() when the first part of a chunk comes in
   *   By havePiece() when somebody got a new piece completed
   *   By chokeMessage() when we receive an unchoke
   *   By setInteresting() when we are now interested
   *   By PeerCoordinator.updatePiecePriorities()
   * </pre>
   */
  synchronized void addRequest() {
    // no bitfield yet? nothing to request then.
    if (bitfield == null) return;
    if (metainfo == null) return;
    boolean more_pieces = true;
    while (more_pieces) {
      more_pieces = outstandingRequests.size() < MAX_PIPELINE;
      // We want something and we don't have outstanding requests?
      if (more_pieces && lastRequest == null) {
        // we have nothing in the queue right now
        if (!interesting) {
          // If we need something, set interesting but delay pulling
          // a request from the PeerCoordinator until unchoked.
          if (listener.needPiece(this.peer, bitfield)) {
            setInteresting(true);
            if (_log.shouldLog(Log.DEBUG))
              _log.debug(
                  peer
                      + " addRequest() we need something, setting interesting, delaying requestNextPiece()");
          } else {
            if (_log.shouldLog(Log.DEBUG)) _log.debug(peer + " addRequest() needs nothing");
          }
          return;
        }
        if (choked) {
          // If choked, delay pulling
          // a request from the PeerCoordinator until unchoked.
          if (_log.shouldLog(Log.DEBUG))
            _log.debug(peer + " addRequest() we are choked, delaying requestNextPiece()");
          return;
        }
        // huh? rv unused
        more_pieces = requestNextPiece();
      } else if (more_pieces) // We want something
      {
        int pieceLength;
        boolean isLastChunk;
        pieceLength = metainfo.getPieceLength(lastRequest.getPiece());
        isLastChunk = lastRequest.off + lastRequest.len == pieceLength;

        // Last part of a piece?
        if (isLastChunk) more_pieces = requestNextPiece();
        else {
          PartialPiece nextPiece = lastRequest.getPartialPiece();
          int nextBegin = lastRequest.off + PARTSIZE;
          int maxLength = pieceLength - nextBegin;
          int nextLength = maxLength > PARTSIZE ? PARTSIZE : maxLength;
          Request req = new Request(nextPiece, nextBegin, nextLength);
          outstandingRequests.add(req);
          if (!choked) out.sendRequest(req);
          lastRequest = req;
        }
      }
    }

    // failsafe
    // However this is bad as it thrashes the peer when we change our mind
    // Ticket 691 cause here?
    if (interesting && lastRequest == null && outstandingRequests.isEmpty()) setInteresting(false);

    if (_log.shouldLog(Log.DEBUG)) _log.debug(peer + " requests " + outstandingRequests);
  }