9
/* QMGR_PEER *qmgr_peer_create(job, queue)
13
/* QMGR_PEER *qmgr_peer_find(job, queue)
17
/* void qmgr_peer_free(peer)
20
/* QMGR_PEER *qmgr_peer_select(job)
24
/* These routines add/delete/manipulate per-job peers.
25
/* Each queue corresponds to a specific job and destination.
26
/* It is similar to per-transport queue structure, but groups
27
/* only the entries of the given job.
29
/* qmgr_peer_create() creates an empty peer structure for the named
30
/* job and destination. It is an error to call this function
31
/* if a peer for given combination already exists.
33
/* qmgr_peer_find() looks up the peer for the named destination
34
/* for the named job. A null result means that the peer
37
/* qmgr_peer_free() disposes of a per-job peer after all
38
/* its entries have been taken care of. It is an error to dispose
39
/* of a peer still in use.
41
/* qmgr_peer_select() attempts to find a peer of named job that
42
/* has messages pending delivery. This routine implements
43
/* round-robin search among job's peers.
45
/* Panic: consistency check failure.
49
/* The Secure Mailer license must be distributed with this software.
59
/* Utility library. */
65
/* Application-specific. */
69
/* qmgr_peer_create - create and initialize message peer structure */
71
QMGR_PEER *qmgr_peer_create(QMGR_JOB *job, QMGR_QUEUE *queue)
75
peer = (QMGR_PEER *) mymalloc(sizeof(QMGR_PEER));
78
QMGR_LIST_APPEND(job->peer_list, peer, peers);
79
htable_enter(job->peer_byname, queue->name, (char *) peer);
81
QMGR_LIST_INIT(peer->entry_list);
85
/* qmgr_peer_free - release peer structure */
87
void qmgr_peer_free(QMGR_PEER *peer)
89
char *myname = "qmgr_peer_free";
90
QMGR_JOB *job = peer->job;
91
QMGR_QUEUE *queue = peer->queue;
94
* Sanity checks. It is an error to delete a referenced peer structure.
96
if (peer->refcount != 0)
97
msg_panic("%s: refcount: %d", myname, peer->refcount);
98
if (peer->entry_list.next != 0)
99
msg_panic("%s: entry list not empty: %s", myname, queue->name);
101
QMGR_LIST_UNLINK(job->peer_list, QMGR_PEER *, peer, peers);
102
htable_delete(job->peer_byname, queue->name, (void (*) (char *)) 0);
103
myfree((char *) peer);
106
/* qmgr_peer_find - lookup peer associated with given job and queue */
108
QMGR_PEER *qmgr_peer_find(QMGR_JOB *job, QMGR_QUEUE *queue)
110
return ((QMGR_PEER *) htable_find(job->peer_byname, queue->name));
113
/* qmgr_peer_select - select next peer suitable for delivery within given job */
115
QMGR_PEER *qmgr_peer_select(QMGR_JOB *job)
121
* If we find a suitable site, rotate the list to enforce round-robin
122
* selection. See similar selection code in qmgr_transport_select().
124
for (peer = job->peer_list.next; peer; peer = peer->peers.next) {
126
if (queue->window > queue->busy_refcount && peer->entry_list.next != 0) {
127
QMGR_LIST_ROTATE(job->peer_list, peer, peers);
129
msg_info("qmgr_peer_select: %s %s %s (%d of %d)",
130
job->message->queue_id, queue->transport->name, queue->name,
131
queue->busy_refcount + 1, queue->window);