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);
}

Reply via email to