46 #define QMGR_LIST_ROTATE(head, object) { \
47 head.next->peers.prev = head.prev; \
48 head.prev->peers.next = head.next; \
49 head.next = object->peers.next; \
50 if (object->peers.next) \
51 head.next->peers.prev = 0; \
53 object->peers.next = 0; \
56 #define QMGR_LIST_UNLINK(head, type, object) { \
57 type next = object->peers.next; \
58 type prev = object->peers.prev; \
59 if (prev) prev->peers.next = next; \
60 else head.next = next; \
61 if (next) next->peers.prev = prev; \
62 else head.prev = prev; \
63 object->peers.next = object->peers.prev = 0; \
66 #define QMGR_LIST_APPEND(head, object) { \
67 object->peers.next = head.next; \
68 object->peers.prev = 0; \
70 head.next->peers.prev = object; \
77 #define QMGR_LIST_PREPEND(head, object) { \
78 object->peers.prev = head.prev; \
79 object->peers.next = 0; \
81 head.prev->peers.next = object; \
88 #define QMGR_LIST_INIT(head) { \
119 #define QMGR_FEEDBACK_IDX_NONE 0
120 #define QMGR_FEEDBACK_IDX_WIN 1
122 #define QMGR_FEEDBACK_IDX_SQRT_WIN 2
125 #ifdef QMGR_FEEDBACK_IDX_SQRT_WIN
131 #ifndef QMGR_FEEDBACK_IDX_SQRT_WIN
132 #define QMGR_FEEDBACK_VAL(fb, win) \
133 ((fb).index == QMGR_FEEDBACK_IDX_NONE ? (fb).base : (fb).base / (win))
135 #define QMGR_FEEDBACK_VAL(fb, win) \
136 ((fb).index == QMGR_FEEDBACK_IDX_NONE ? (fb).base : \
137 (fb).index == QMGR_FEEDBACK_IDX_WIN ? (fb).base / (win) : \
138 (fb).base / sqrt(win))
170 #define QMGR_TRANSPORT_STAT_DEAD (1<<1)
171 #define QMGR_TRANSPORT_STAT_RATE_LOCK (1<<2)
181 #define QMGR_TRANSPORT_THROTTLED(t) ((t)->flags & QMGR_TRANSPORT_STAT_DEAD)
216 #define QMGR_QUEUE_TODO 1
217 #define QMGR_QUEUE_BUSY 2
239 #define QMGR_QUEUE_STAT_THROTTLED 0
240 #define QMGR_QUEUE_STAT_SUSPENDED -1
241 #define QMGR_QUEUE_STAT_SAVED -2
242 #define QMGR_QUEUE_STAT_BAD -3
244 #define QMGR_QUEUE_READY(q) ((q)->window > 0)
245 #define QMGR_QUEUE_THROTTLED(q) ((q)->window == QMGR_QUEUE_STAT_THROTTLED)
246 #define QMGR_QUEUE_SUSPENDED(q) ((q)->window == QMGR_QUEUE_STAT_SUSPENDED)
247 #define QMGR_QUEUE_SAVED(q) ((q)->window == QMGR_QUEUE_STAT_SAVED)
248 #define QMGR_QUEUE_BAD(q) ((q)->window <= QMGR_QUEUE_STAT_BAD)
250 #define QMGR_QUEUE_STATUS(q) ( \
251 QMGR_QUEUE_READY(q) ? "ready" : \
252 QMGR_QUEUE_THROTTLED(q) ? "throttled" : \
253 QMGR_QUEUE_SUSPENDED(q) ? "suspended" : \
254 QMGR_QUEUE_SAVED(q) ? "saved" : \
255 "invalid queue status" \
327 #define QMGR_READ_FLAG_SEEN_ALL_NON_RCPT (1<<16)
329 #define QMGR_MESSAGE_LOCKED ((QMGR_MESSAGE *) 1)
341 #define QMGR_MSG_STATS(stats, message) \
342 MSG_STATS_INIT2(stats, \
343 incoming_arrival, message->arrival_time, \
344 active_arrival, message->active_time)
374 extern void qmgr_move(
const char *,
const char *, time_t);
397 #define QMGR_SCAN_START (1<<0)
398 #define QMGR_SCAN_ALL (1<<1)
399 #define QMGR_FLUSH_ONCE (1<<2)
400 #define QMGR_FLUSH_DFXP (1<<3)
401 #define QMGR_FLUSH_EACH (1<<4)
int qmgr_active_feed(QMGR_SCAN *, const char *)
QMGR_QUEUE * qmgr_error_queue(const char *, DSN *)
void qmgr_message_free(QMGR_MESSAGE *)
int dest_concurrency_limit
void qmgr_message_kill_record(QMGR_MESSAGE *, long)
QMGR_TRANSPORT * qmgr_transport_create(const char *)
struct timeval active_time
QMGR_TRANSPORT * qmgr_error_transport(const char *)
QMGR_QUEUE * qmgr_queue_select(QMGR_TRANSPORT *)
void qmgr_queue_suspend(QMGR_QUEUE *, int)
QMGR_FEEDBACK neg_feedback
void qmgr_entry_move_todo(QMGR_QUEUE *, QMGR_ENTRY *)
QMGR_QUEUE * qmgr_queue_create(QMGR_TRANSPORT *, const char *, const char *)
void qmgr_bounce_recipient(QMGR_MESSAGE *, RECIPIENT *, DSN *)
int init_dest_concurrency
void qmgr_message_update_warn(QMGR_MESSAGE *)
QMGR_SCAN * qmgr_scan_create(const char *)
void qmgr_queue_unthrottle(QMGR_QUEUE *)
QMGR_MESSAGE * qmgr_message_alloc(const char *, const char *, int, mode_t)
struct timeval arrival_time
struct HTABLE * queue_byname
QMGR_TRANSPORT * qmgr_transport_find(const char *)
QMGR_MESSAGE * qmgr_message_realloc(QMGR_MESSAGE *)
void qmgr_active_drain(void)
void qmgr_scan_request(QMGR_SCAN *, int)
QMGR_QUEUE * qmgr_queue_find(QMGR_TRANSPORT *, const char *)
QMGR_ENTRY * qmgr_entry_create(QMGR_QUEUE *, QMGR_MESSAGE *)
void qmgr_enable_queue(QMGR_QUEUE *)
void qmgr_queue_done(QMGR_QUEUE *)
void qmgr_queue_throttle(QMGR_QUEUE *, DSN *)
void qmgr_active_done(QMGR_MESSAGE *)
void qmgr_entry_unselect(QMGR_QUEUE *, QMGR_ENTRY *)
QMGR_TRANSPORT_LIST peers
QMGR_ENTRY * qmgr_entry_select(QMGR_QUEUE *)
void qmgr_defer_transport(QMGR_TRANSPORT *, DSN *)
void qmgr_entry_done(QMGR_ENTRY *, int)
int qmgr_deliver_concurrency
void qmgr_deliver(QMGR_TRANSPORT *, VSTREAM *)
void qmgr_transport_throttle(QMGR_TRANSPORT *, DSN *)
void qmgr_enable_all(void)
void qmgr_defer_recipient(QMGR_MESSAGE *, RECIPIENT *, DSN *)
QMGR_TRANSPORT * transport
void qmgr_transport_unthrottle(QMGR_TRANSPORT *)
void qmgr_enable_transport(QMGR_TRANSPORT *)
void qmgr_defer_todo(QMGR_QUEUE *, DSN *)
void qmgr_transport_alloc(QMGR_TRANSPORT *, QMGR_TRANSPORT_ALLOC_NOTIFY)
QMGR_QUEUE_LIST queue_list
void qmgr_feedback_init(QMGR_FEEDBACK *, const char *, const char *, const char *, const char *)
QMGR_TRANSPORT * qmgr_transport_select(void)
char * qmgr_error_nexthop(DSN *)
void qmgr_move(const char *, const char *, time_t)
QMGR_FEEDBACK pos_feedback
QMGR_TRANSPORT_LIST qmgr_transport_list
struct HTABLE * qmgr_transport_byname
char * qmgr_scan_next(QMGR_SCAN *)
void(* QMGR_TRANSPORT_ALLOC_NOTIFY)(QMGR_TRANSPORT *, VSTREAM *)