QMGR_QUEUE *qmgr_queue_select(QMGR_TRANSPORT *transport) { QMGR_QUEUE *queue; /* * If we find a suitable site, rotate the list to enforce round-robin * selection. See similar selection code in qmgr_transport_select(). */ for (queue = transport->queue_list.next; queue; queue = queue->peers.next) { if (queue->window > queue->busy_refcount && queue->todo.next != 0) { QMGR_LIST_ROTATE(transport->queue_list, queue); if (msg_verbose) msg_info("qmgr_queue_select: %s", queue->name); return (queue); } } return (0); }
QMGR_PEER *qmgr_peer_select(QMGR_JOB *job) { QMGR_PEER *peer; QMGR_QUEUE *queue; /* * If we find a suitable site, rotate the list to enforce round-robin * selection. See similar selection code in qmgr_transport_select(). */ for (peer = job->peer_list.next; peer; peer = peer->peers.next) { queue = peer->queue; if (queue->window > queue->busy_refcount && peer->entry_list.next != 0) { QMGR_LIST_ROTATE(job->peer_list, peer, peers); if (msg_verbose) msg_info("qmgr_peer_select: %s %s %s (%d of %d)", job->message->queue_id, queue->transport->name, queue->name, queue->busy_refcount + 1, queue->window); return (peer); } } return (0); }
QMGR_TRANSPORT *qmgr_transport_select(void) { QMGR_TRANSPORT *xport; QMGR_QUEUE *queue; int need; /* * If we find a suitable transport, rotate the list of transports to * effectuate round-robin selection. See similar selection code in * qmgr_peer_select(). * * This function is called repeatedly until all transports have maxed out * the number of pending delivery agent connections, until all delivery * agent concurrency windows are maxed out, or until we run out of "todo" * queue entries. */ #define MIN5af51743e4eef(x, y) ((x) < (y) ? (x) : (y)) for (xport = qmgr_transport_list.next; xport; xport = xport->peers.next) { if ((xport->flags & QMGR_TRANSPORT_STAT_DEAD) != 0 || (xport->flags & QMGR_TRANSPORT_STAT_RATE_LOCK) != 0 || xport->pending >= QMGR_TRANSPORT_MAX_PEND) continue; need = xport->pending + 1; for (queue = xport->queue_list.next; queue; queue = queue->peers.next) { if (QMGR_QUEUE_READY(queue) == 0) continue; if ((need -= MIN5af51743e4eef(queue->window - queue->busy_refcount, queue->todo_refcount)) <= 0) { QMGR_LIST_ROTATE(qmgr_transport_list, xport, peers); if (msg_verbose) msg_info("qmgr_transport_select: %s", xport->name); return (xport); } } } return (0); }