/*
* Copyright (c) 2003-2005 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 2006 Claus Assmann
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*
* $Id: aqrdq.h,v 1.19 2006/11/13 02:10:17 ca Exp $
*/
#ifndef SM_AQRDQ_H
#define SM_AQRDQ_H 1
#include "sm/generic.h"
#include "sm/magic.h"
#include "sm/types.h"
#include "sm/time.h"
#include "sm/pthread.h"
#include "sm/net.h"
#include "sm/bhtable.h"
#include "sm/ringhd.h"
#include "sm/queue.h"
#include "sm/actdb.h"
#include "sm/aqrdqstr.h"
#include "sm/log.h"
#ifndef AQRDQ_CHECK
# define AQRDQ_CHECK 1
#endif
/*
** Active Queue Recipient Destination Queue
** These entries are accessed via a hash table from AQ (aq_ctx->aq_rdq_ht).
** They store information about (rcpt) entries in AQ that are
** being sent/destined to the same destination (only IPv4 address currently).
**
** XXX Note: DA idx is NOT used. It must be part of the key for lookups!
*/
struct aqrdq_ctx_S
{
#if AQRDQ_CHECK
sm_magic_T sm_magic;
#endif
/*
this probably needs individual locking!
pthread_mutex_t aqrdq_mutex;
*/
uint aqrdq_da; /* DA index */
ipv4_T aqrdq_srv_ipv4; /* XXX HACK! */
uint32_t aqrdq_flags;
uint aqrdq_entries;
#if 0
// uint aqrdq_entries_max;
#endif
aq_rcpts_T aqrdq_rcpts;
/*
** This is used to
** - keep a "cache" of aqrdq_ctx_P, compare
** occ_entry_P and libdadb/occh.c: occ_entry_new/free
** XXX not yet implemented.
** - link "used" entries together, then the scheduler
** can "walk" through the list.
** Use a double-linked list go get fancier operations, e.g.,
** "rotate" the queue, so the head points to the "next" ctx
** that should be scheduled (rotation would introduce some kind
** of fairness).
*/
TAILQ_ENTRY(aqrdq_ctx_S) aqrdq_link;
};
/* AQRDQ ctx flags */
#define AQRDQ_FL_NONE 0x0000 /* guess */
#define AQRDQ_FL_USED 0x0001 /* in use */
#define AQRDQ_FL_OCEXC 0x0002 /* number of open sessions exceeded */
/* not checked anywhere (yet) */
/* TA is waiting, inform scheduler when a transaction is done */
/* #define AQRDQ_FL_TA_WAIT 0x0004 * not yet used */
#define AQRDQ_SET_FLAG(aqrdq_ctx, fl) (aqrdq_ctx)->aqrdq_flags |= (fl)
#define AQRDQ_CLR_FLAG(aqrdq_ctx, fl) (aqrdq_ctx)->aqrdq_flags &= ~(fl)
#define AQRDQ_IS_FLAG(aqrdq_ctx, fl) (((aqrdq_ctx)->aqrdq_flags & (fl)) != 0)
#if 0
/* Operations on aq_rcpt lists */
//#define AQR_RDQ_INIT(hd) SM_RINGHD_INIT(hd)
//#define AQR_RDQ_APP(hd, aq_rcpt) SM_RINGHD_APPEND((hd), (aq_rcpt), aqr_dest_link)
//#define AQR_RDQ_DELENTRY(hd, aq_rcpt) SM_RINGHD_DELENTRY((hd), AQR_DEST2R(aq_rcpt))
#endif /* 0 */
/* Operations on aq_rcpt lists (in AQ RDQ) */
#define AQ_RDQ_INIT(aqrdq) TAILQ_INIT(&(aqrdq))
#define AQ_RDQ_EMPTY(aqrdq) TAILQ_EMPTY(&(aqrdq))
#define AQ_RDQ_FIRST(aqrdq) TAILQ_FIRST(&(aqrdq))
#define AQ_RDQ_END(aqrdq) TAILQ_END(&(aqrdq))
#define AQ_RDQ_LAST(aqrdq) TAILQ_LAST(&(aqrdq), aq_rcpts_S)
#define AQ_RDQ_NEXT(aq_rcpt) TAILQ_NEXT(aq_rcpt, aqr_dest_link)
#define AQ_RDQ_INSERT_TAIL(aqrdq, aq_rcpt) TAILQ_INSERT_TAIL(&(aqrdq), aq_rcpt, aqr_dest_link)
#define AQ_RDQ_INSERT_HEAD(aqrdq, aq_rcpt) TAILQ_INSERT_HEAD(&(aqrdq), aq_rcpt, aqr_dest_link)
#define AQ_RDQ_REMOVE(aqrdq, aq_rcpt) TAILQ_REMOVE(&(aqrdq), aq_rcpt, aqr_dest_link)
/* Operations on aqrdq_ctx lists (in AQ) */
#define AQ_RDQS_INIT(aqrdqs) TAILQ_INIT(&(aqrdqs))
#define AQ_RDQS_FIRST(aqrdqs) TAILQ_FIRST(&(aqrdqs))
#define AQ_RDQS_END(aqrdqs) TAILQ_END(&(aqrdqs))
#define AQ_RDQS_NEXT(aqrdq_ctx) TAILQ_NEXT(aqrdq_ctx, aqrdq_link)
#define AQ_RDQS_INSERT_TAIL(aqrdqs, aqrdq_ctx) TAILQ_INSERT_TAIL(&(aqrdqs), aqrdq_ctx, aqrdq_link)
#define AQ_RDQS_INSERT_HEAD(aqrdqs, aqrdq_ctx) TAILQ_INSERT_HEAD(&(aqrdqs), aqrdq_ctx, aqrdq_link)
#define AQ_RDQS_REMOVE(aqrdqs, aqrdq_ctx) TAILQ_REMOVE(&(aqrdqs), aqrdq_ctx, aqrdq_link)
#if AQRDQ_CHECK
# define SM_IS_AQRDQE(aqrdq_ctx) SM_REQUIRE_ISA((aqrdq_ctx), SM_AQRDQ_MAGIC)
#else
# define SM_IS_AQRDQE(aqrdq_ctx) SM_REQUIRE((aqrdq_ctx) != NULL)
#endif
sm_ret_T aq_rdq_add(aq_ctx_P _aq_ctx, aq_rcpt_P _aq_rcpt, uint32_t *_paqrdq_flags, thr_lock_T _locktype);
sm_ret_T aq_rdq_rm(aq_ctx_P _aq_ctx, aq_rcpt_P _aq_rcpt, thr_lock_T _locktype, sm_log_ctx_P _lctx);
sm_ret_T aq_rdq_find(aq_ctx_P _aq_ctx, ipv4_T _ipv4, aqrdq_ctx_P *_paqrdq_ctx, thr_lock_T _locktype);
#endif /* SM_AQRDQ_H */
syntax highlighted by Code2HTML, v. 0.9.1