Expand PMF_FN_* macros.
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / qmgr / qmgr_peer.c
blob9b8c5535775b1e1d4ff96fe92efcfd691a3874bd
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* qmgr_peer 3
6 /* SUMMARY
7 /* per-job peers
8 /* SYNOPSIS
9 /* #include "qmgr.h"
11 /* QMGR_PEER *qmgr_peer_create(job, queue)
12 /* QMGR_JOB *job;
13 /* QMGR_QUEUE *queue;
15 /* QMGR_PEER *qmgr_peer_find(job, queue)
16 /* QMGR_JOB *job;
17 /* QMGR_QUEUE *queue;
19 /* QMGR_PEER *qmgr_peer_obtain(job, queue)
20 /* QMGR_JOB *job;
21 /* QMGR_QUEUE *queue;
23 /* void qmgr_peer_free(peer)
24 /* QMGR_PEER *peer;
26 /* QMGR_PEER *qmgr_peer_select(job)
27 /* QMGR_JOB *job;
29 /* DESCRIPTION
30 /* These routines add/delete/manipulate per-job peers.
31 /* Each peer corresponds to a specific job and destination.
32 /* It is similar to per-transport queue structure, but groups
33 /* only the entries of the given job.
35 /* qmgr_peer_create() creates an empty peer structure for the named
36 /* job and destination. It is an error to call this function
37 /* if a peer for given combination already exists.
39 /* qmgr_peer_find() looks up the peer for the named destination
40 /* for the named job. A null result means that the peer
41 /* was not found.
43 /* qmgr_peer_obtain() looks up the peer for the named destination
44 /* for the named job. If it doesn't exist yet, it creates it.
46 /* qmgr_peer_free() disposes of a per-job peer after all
47 /* its entries have been taken care of. It is an error to dispose
48 /* of a peer still in use.
50 /* qmgr_peer_select() attempts to find a peer of named job that
51 /* has messages pending delivery. This routine implements
52 /* round-robin search among job's peers.
53 /* DIAGNOSTICS
54 /* Panic: consistency check failure.
55 /* LICENSE
56 /* .ad
57 /* .fi
58 /* The Secure Mailer license must be distributed with this software.
59 /* AUTHOR(S)
60 /* Patrik Rak
61 /* patrik@raxoft.cz
62 /*--*/
64 /* System library. */
66 #include <sys_defs.h>
68 /* Utility library. */
70 #include <msg.h>
71 #include <htable.h>
72 #include <mymalloc.h>
74 /* Application-specific. */
76 #include "qmgr.h"
78 /* qmgr_peer_create - create and initialize message peer structure */
80 QMGR_PEER *qmgr_peer_create(QMGR_JOB *job, QMGR_QUEUE *queue)
82 QMGR_PEER *peer;
84 peer = (QMGR_PEER *) mymalloc(sizeof(QMGR_PEER));
85 peer->queue = queue;
86 peer->job = job;
87 QMGR_LIST_APPEND(job->peer_list, peer, peers);
88 htable_enter(job->peer_byname, queue->name, (char *) peer);
89 peer->refcount = 0;
90 QMGR_LIST_INIT(peer->entry_list);
91 return (peer);
94 /* qmgr_peer_free - release peer structure */
96 void qmgr_peer_free(QMGR_PEER *peer)
98 const char *myname = "qmgr_peer_free";
99 QMGR_JOB *job = peer->job;
100 QMGR_QUEUE *queue = peer->queue;
103 * Sanity checks. It is an error to delete a referenced peer structure.
105 if (peer->refcount != 0)
106 msg_panic("%s: refcount: %d", myname, peer->refcount);
107 if (peer->entry_list.next != 0)
108 msg_panic("%s: entry list not empty: %s", myname, queue->name);
110 QMGR_LIST_UNLINK(job->peer_list, QMGR_PEER *, peer, peers);
111 htable_delete(job->peer_byname, queue->name, (void (*) (char *)) 0);
112 myfree((char *) peer);
115 /* qmgr_peer_find - lookup peer associated with given job and queue */
117 QMGR_PEER *qmgr_peer_find(QMGR_JOB *job, QMGR_QUEUE *queue)
119 return ((QMGR_PEER *) htable_find(job->peer_byname, queue->name));
122 /* qmgr_peer_obtain - find/create peer associated with given job and queue */
124 QMGR_PEER *qmgr_peer_obtain(QMGR_JOB *job, QMGR_QUEUE *queue)
126 QMGR_PEER *peer;
128 if ((peer = qmgr_peer_find(job, queue)) == 0)
129 peer = qmgr_peer_create(job, queue);
130 return (peer);
133 /* qmgr_peer_select - select next peer suitable for delivery within given job */
135 QMGR_PEER *qmgr_peer_select(QMGR_JOB *job)
137 QMGR_PEER *peer;
138 QMGR_QUEUE *queue;
141 * If we find a suitable site, rotate the list to enforce round-robin
142 * selection. See similar selection code in qmgr_transport_select().
144 for (peer = job->peer_list.next; peer; peer = peer->peers.next) {
145 queue = peer->queue;
146 if (queue->window > queue->busy_refcount && peer->entry_list.next != 0) {
147 QMGR_LIST_ROTATE(job->peer_list, peer, peers);
148 if (msg_verbose)
149 msg_info("qmgr_peer_select: %s %s %s (%d of %d)",
150 job->message->queue_id, queue->transport->name, queue->name,
151 queue->busy_refcount + 1, queue->window);
152 return (peer);
155 return (0);