/* * Copyright (c) 2002-2005 Sendmail, Inc. and its suppliers. * All rights reserved. * * 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: edb-int.h,v 1.25 2006/12/29 03:14:26 ca Exp $ */ #ifndef SM_EDB_INT_H #define SM_EDB_INT_H 1 #include "sm/generic.h" #include "sm/magic.h" #include "sm/error.h" #include "sm/memops.h" #include "sm/assert.h" #include "sm/edb.h" #include "sm/log.h" #ifndef EDB_DEBUG # define EDB_DEBUG 0 #endif #if EDB_DEBUG # define EDB_DPRINTF(x) sm_io_fprintf x #else # define EDB_DPRINTF(x) #endif /* ** EDB context ** This structure contains all information for DEFEDB. ** ** It contains a write request list which stores a list of EDB requests ** (see above). ** ** Notes: ** - functions can create their own request lists which is passed ** to the various edb_ functions: if it is NULL then edb_reql_wr ** is used otherwise the parameter. ** - write requests must be (partially) ordered, i.e., if two ** request lists contain updates for the same item (TA/RCPT), ** then their order must be preserved. This order must be ** enforced by the application, it can't rely on the scheduler ** (since this is a multi-threaded program). ** To simplify implementation, a strict ordering is required ** (for now). ** How to enforce ordering? ** Have a list of request lists... (fixed size?) ** simple algorithm: ** give each request list a number ** store the first and last active number here ** if a request comes in, compare the number with first ** while rq_number != first: wait ** if rq_number == first: write ** use a mutex and a condition variable */ struct edb_ctx_S { sm_magic_T sm_magic; pthread_mutex_t edb_mutex; /* only one mutex for now */ uint edb_entries; /* current number of entries */ #if 0 sm_rcb_P edb_rd_rcb; #endif edb_req_hd_T edb_reql_wr; /* request list (wr) */ /* checkpoint data: minimum KBytes, delay (s) */ uint32_t edb_chkpt_kb; uint32_t edb_chkpt_delay; /* number of writes since last checkpoint */ uint32_t edb_writes; #if 0 time_T edb_last_write; #endif char edb_pfx[8]; /* error prefix "errpfx" for BDB */ sm_log_ctx_P edb_lctx; /* logging context */ /* ** Pool of edb_req(uests) for reuse. ** Possible optimizations: ** - Preallocate some entries ** - If there are more than U(pper) entries, free some ** such that only L(ower) are in the list. */ edb_req_hd_T edb_reql_fls; /* small requests */ edb_req_hd_T edb_reql_fln; /* normal (large) requests */ #if SM_REQL_FLE edb_req_hd_T edb_reql_fle; /* "emergency" (large) requests */ #endif DB_ENV *edb_bdbenv; DB *edb_bdb; /* Berkeley DB */ }; /* current version (16 bits major/8 bits minor/8 bits patchlevel) */ #define EDB_VERSION 0x00010300 #define EDB_VRS_MAJ(v) ((v) & 0x7FFF0000) #define EDB_VRS_MIN(v) ((v) & 0x0000FF00) #define EDB_VRS_PL(v) ((v) & 0x000000FF) #define EDB_VRS_COMPAT(new, old) (((new) == (old)) || \ (EDB_VRS_MAJ(new) == EDB_VRS_MAJ(old) && \ EDB_VRS_MIN(new) >= EDB_VRS_MIN(old))) #define EDB_VRS_KEY "EDB_VERSION" sm_ret_T edb_reqls_free(edb_ctx_P _edb_ctx); #define SM_IS_EDB_CTX(edb_ctx) SM_REQUIRE_ISA((edb_ctx), SM_EDB_CTX_MAGIC) #endif /* ! SM_EDB_INT_H */