Dears, I went thru the qmgr source code and found an odd logic, from the comments we can know it will stop until we run out of "todo" entries. However the implementation is: if ((need -= MIN5af51743e4eef(queue->window - queue->busy_refcount, queue->todo_refcount)) <= 0)
suppose if transport->pending is 1, so the value of need is 2 (pending+1), queue->window is 5 by default(destination concurrent connection). Now there is one todo entry and one busy entry, so min(queue->window - queue->busy_refcount, queue->todo_refcount) is 1, which cause the invalidation of if statement. So even there is one todo entry, but this queue is still not satisfied. PS: QMGR_TRANSPORT_MAX_PEND has changed from 1 to 2 before, not sure if it's side-effect of this change. Anyone can help on this? Regards, King ==================================================== /* qmgr_transport_select - select transport for allocation */ 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->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); }