# File lib/rubytorrent/controller.rb, line 248
  def add_peer(p)
    accept = true

    if @peers.length >= MAX_PEERS && !@package.complete?
      oldp = @peers.find { |x| !x.running? || ((x.dlamt == 0) && ((Time.now - x.start_time) > BOREDOM_DEATH_INTERVAL)) }

      if oldp
        rt_debug "killing peer for being boring: #{oldp}" 
        oldp.shutdown
      else
        rt_debug "too many peers, ignoring #{p}"
        p.shutdown
        accept = false
      end
    end

    if accept
      p.on_event(self, :received_block) { |peer, block| received_block(block, peer) }
      p.on_event(self, :peer_has_piece) { |peer, piece| peer_has_piece(piece, peer) }
      p.on_event(self, :peer_has_pieces) { |peer, bitfield| peer_has_pieces(bitfield, peer) }
      p.on_event(self, :sent_block) { |peer, block| send_event(:sent_block, block, peer.name) }
      p.on_event(self, :requested_block) { |peer, block| send_event(:requested_block, block, peer.name) }

      @peers_m.synchronize do
        @peers.push p
        ## it's important not to call p.start (which triggers the
        ## bitfield message) until it's been added to @peer, such that
        ## any :have messages that might happen from other peers in
        ## the mean time are propagated to it.
        ##
        ## of course that means we need to call p.start within the
        ## mutex context so that the reaper section of the heartbeat
        ## doesn't kill it between push and start.
        ##
        ## ah, the joys of threaded programming.
        p.start if @running
      end

      send_event(:added_peer, p.name)
    end
  end