/*
* 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 */
syntax highlighted by Code2HTML, v. 0.9.1