Postfix3.3.1
qmgr_peer.c
[詳解]
1 /*++
2 /* NAME
3 /* qmgr_peer 3
4 /* SUMMARY
5 /* per-job peers
6 /* SYNOPSIS
7 /* #include "qmgr.h"
8 /*
9 /* QMGR_PEER *qmgr_peer_create(job, queue)
10 /* QMGR_JOB *job;
11 /* QMGR_QUEUE *queue;
12 /*
13 /* QMGR_PEER *qmgr_peer_find(job, queue)
14 /* QMGR_JOB *job;
15 /* QMGR_QUEUE *queue;
16 /*
17 /* QMGR_PEER *qmgr_peer_obtain(job, queue)
18 /* QMGR_JOB *job;
19 /* QMGR_QUEUE *queue;
20 /*
21 /* void qmgr_peer_free(peer)
22 /* QMGR_PEER *peer;
23 /*
24 /* QMGR_PEER *qmgr_peer_select(job)
25 /* QMGR_JOB *job;
26 /*
27 /* DESCRIPTION
28 /* These routines add/delete/manipulate per-job peers.
29 /* Each peer corresponds to a specific job and destination.
30 /* It is similar to per-transport queue structure, but groups
31 /* only the entries of the given job.
32 /*
33 /* qmgr_peer_create() creates an empty peer structure for the named
34 /* job and destination. It is an error to call this function
35 /* if a peer for given combination already exists.
36 /*
37 /* qmgr_peer_find() looks up the peer for the named destination
38 /* for the named job. A null result means that the peer
39 /* was not found.
40 /*
41 /* qmgr_peer_obtain() looks up the peer for the named destination
42 /* for the named job. If it doesn't exist yet, it creates it.
43 /*
44 /* qmgr_peer_free() disposes of a per-job peer after all
45 /* its entries have been taken care of. It is an error to dispose
46 /* of a peer still in use.
47 /*
48 /* qmgr_peer_select() attempts to find a peer of named job that
49 /* has messages pending delivery. This routine implements
50 /* round-robin search among job's peers.
51 /* DIAGNOSTICS
52 /* Panic: consistency check failure.
53 /* LICENSE
54 /* .ad
55 /* .fi
56 /* The Secure Mailer license must be distributed with this software.
57 /* AUTHOR(S)
58 /* Patrik Rak
59 /* patrik@raxoft.cz
60 /*--*/
61 
62 /* System library. */
63 
64 #include <sys_defs.h>
65 
66 /* Utility library. */
67 
68 #include <msg.h>
69 #include <htable.h>
70 #include <mymalloc.h>
71 
72 /* Application-specific. */
73 
74 #include "qmgr.h"
75 
76 /* qmgr_peer_create - create and initialize message peer structure */
77 
79 {
80  QMGR_PEER *peer;
81 
82  peer = (QMGR_PEER *) mymalloc(sizeof(QMGR_PEER));
83  peer->queue = queue;
84  peer->job = job;
85  QMGR_LIST_APPEND(job->peer_list, peer, peers);
86  htable_enter(job->peer_byname, queue->name, (void *) peer);
87  peer->refcount = 0;
89  return (peer);
90 }
91 
92 /* qmgr_peer_free - release peer structure */
93 
95 {
96  const char *myname = "qmgr_peer_free";
97  QMGR_JOB *job = peer->job;
98  QMGR_QUEUE *queue = peer->queue;
99 
100  /*
101  * Sanity checks. It is an error to delete a referenced peer structure.
102  */
103  if (peer->refcount != 0)
104  msg_panic("%s: refcount: %d", myname, peer->refcount);
105  if (peer->entry_list.next != 0)
106  msg_panic("%s: entry list not empty: %s", myname, queue->name);
107 
108  QMGR_LIST_UNLINK(job->peer_list, QMGR_PEER *, peer, peers);
109  htable_delete(job->peer_byname, queue->name, (void (*) (void *)) 0);
110  myfree((void *) peer);
111 }
112 
113 /* qmgr_peer_find - lookup peer associated with given job and queue */
114 
116 {
117  return ((QMGR_PEER *) htable_find(job->peer_byname, queue->name));
118 }
119 
120 /* qmgr_peer_obtain - find/create peer associated with given job and queue */
121 
123 {
124  QMGR_PEER *peer;
125 
126  if ((peer = qmgr_peer_find(job, queue)) == 0)
127  peer = qmgr_peer_create(job, queue);
128  return (peer);
129 }
130 
131 /* qmgr_peer_select - select next peer suitable for delivery within given job */
132 
134 {
135  QMGR_PEER *peer;
136  QMGR_QUEUE *queue;
137 
138  /*
139  * If we find a suitable site, rotate the list to enforce round-robin
140  * selection. See similar selection code in qmgr_transport_select().
141  */
142  for (peer = job->peer_list.next; peer; peer = peer->peers.next) {
143  queue = peer->queue;
144  if (queue->window > queue->busy_refcount && peer->entry_list.next != 0) {
145  QMGR_LIST_ROTATE(job->peer_list, peer, peers);
146  if (msg_verbose)
147  msg_info("qmgr_peer_select: %s %s %s (%d of %d)",
148  job->message->queue_id, queue->transport->name, queue->name,
149  queue->busy_refcount + 1, queue->window);
150  return (peer);
151  }
152  }
153  return (0);
154 }
int msg_verbose
Definition: msg.c:177
QMGR_PEER * qmgr_peer_select(QMGR_JOB *job)
Definition: qmgr_peer.c:133
QMGR_ENTRY * next
Definition: qmgr.h:193
void myfree(void *ptr)
Definition: mymalloc.c:207
char * queue_id
Definition: qmgr.h:298
NORETURN msg_panic(const char *fmt,...)
Definition: msg.c:295
QMGR_PEER_LIST peers
Definition: qmgr.h:439
QMGR_PEER * qmgr_peer_create(QMGR_JOB *job, QMGR_QUEUE *queue)
Definition: qmgr_peer.c:78
void qmgr_peer_free(QMGR_PEER *peer)
Definition: qmgr_peer.c:94
struct HTABLE * peer_byname
Definition: qmgr.h:420
#define QMGR_LIST_INIT(head)
Definition: qmgr.h:88
#define QMGR_LIST_APPEND(head, object)
Definition: qmgr.h:66
#define QMGR_LIST_ROTATE(head, object)
Definition: qmgr.h:46
int busy_refcount
Definition: qmgr.h:203
char * name
Definition: qmgr.h:200
int refcount
Definition: qmgr.h:436
void * htable_find(HTABLE *table, const char *key)
Definition: htable.c:227
char * name
Definition: qmgr.h:155
Definition: qmgr.h:408
QMGR_TRANSPORT * transport
Definition: qmgr.h:208
#define QMGR_LIST_UNLINK(head, type, object)
Definition: qmgr.h:56
QMGR_PEER * qmgr_peer_find(QMGR_JOB *job, QMGR_QUEUE *queue)
Definition: qmgr_peer.c:115
QMGR_QUEUE * queue
Definition: qmgr.h:435
QMGR_JOB * job
Definition: qmgr.h:434
QMGR_PEER * qmgr_peer_obtain(QMGR_JOB *job, QMGR_QUEUE *queue)
Definition: qmgr_peer.c:122
QMGR_PEER_LIST peer_list
Definition: qmgr.h:422
int window
Definition: qmgr.h:204
QMGR_MESSAGE * message
Definition: qmgr.h:409
void htable_delete(HTABLE *table, const char *key, void(*free_fn)(void *))
Definition: htable.c:257
QMGR_ENTRY_LIST entry_list
Definition: qmgr.h:437
QMGR_PEER * next
Definition: qmgr.h:404
void * mymalloc(ssize_t len)
Definition: mymalloc.c:150
HTABLE_INFO * htable_enter(HTABLE *table, const char *key, void *value)
Definition: htable.c:212
void msg_info(const char *fmt,...)
Definition: msg.c:199