/* * Copyright (c) 2002, 2003 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: ring.h,v 1.6 2005/06/16 00:09:34 ca Exp $ */ #ifndef SM_RING_H #define SM_RING_H 1 #include "sm/generic.h" #include "sm/types.h" #ifndef SM_RING_INLINE # define SM_RING_INLINE 0 #endif /* ** A ring is embedded in a structure (see SM_RING_EMBED) ** and is a "circular queue" without a head. */ typedef struct sm_ring_S sm_ring_T, *sm_ring_P; struct sm_ring_S { sm_ring_P sm_rg_succ; sm_ring_P sm_rg_pred; }; void sm_ring_init(sm_ring_P _ring); void sm_ring_prepend(sm_ring_P _ring1, sm_ring_P _ring2); void sm_ring_append(sm_ring_P _ring1, sm_ring_P _ring2); #define SM_RING_INIT(ring) \ do { \ (ring)->sm_rg_pred = (ring)->sm_rg_succ = (ring); \ } while (0) #define SM_RING_APPEND(ring, entry) \ do { \ (entry)->sm_rg_succ = (ring)->sm_rg_succ; \ (entry)->sm_rg_pred = (ring); \ (ring)->sm_rg_succ->sm_rg_pred = (entry); \ (ring)->sm_rg_succ = (entry); \ } while (0) #define SM_RING_PREPEND(ring, entry) \ do { \ (entry)->sm_rg_pred = (ring)->sm_rg_pred; \ (entry)->sm_rg_succ = (ring); \ (ring)->sm_rg_pred->sm_rg_succ = (entry); \ (ring)->sm_rg_pred = (entry); \ } while (0) void sm_ring_delentry(sm_ring_P); #define sm_ring_succ(c) ((c)->sm_rg_succ) #define sm_ring_pred(c) ((c)->sm_rg_pred) #define SM_RING_EMBED(ring_p, struct_S, ring_member) \ ((struct_S *) (((char *) (ring_p)) - offsetof(struct_S, ring_member))) #if 0 Example how to use a ring: get the (address of the) ring in the structure: #define STRUCT_LINK2R(struct) (&((struct)->struct_link)) get from the ring to the structure: #define STRUCT_R2LINK(ring) SM_RING_EMBED((ring), struct, struct_link) define structure specific macros for ring operations by applying the two macros defined above: #define STRUCT_LINK_INIT(struct) SM_RING_INIT(STRUCT_LINK2R(struct)) #define STRUCT_LINK_APP(struct, struct_nxt) SM_RING_APPEND(STRUCT_LINK2R(struct), STRUCT_LINK2R(struct_nxt)) #define STRUCT_LINK_PRE(struct, struct_nxt) SM_RING_PREPEND(STRUCT_LINK2R(struct), STRUCT_LINK2R(struct_nxt)) #define STRUCT_LINK_SUCC(struct) STRUCT_R2LINK(sm_ring_succ(STRUCT_LINK2R(struct))) #define STRUCT_LINK_PRED(struct) STRUCT_R2LINK(sm_ring_pred(STRUCT_LINK2R(struct))) #define STRUCT_LINK_DELENTRY(struct) sm_ring_delentry(STRUCT_LINK2R(struct)) #endif /* 0 */ #endif /* SM_RING_H */