2 * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2001, 2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: refcount.h,v 1.3.2.2.2.2 2004/04/14 05:12:25 marka Exp $ */
20 #ifndef ISC_REFCOUNT_H
21 #define ISC_REFCOUNT_H 1
24 #include <isc/mutex.h>
25 #include <isc/platform.h>
26 #include <isc/types.h>
30 * Implements a locked reference counter. These functions may actually be
31 * implemented using macros, and implementations of these macros are below.
32 * The isc_refcount_t type should not be accessed directly, as its contents
33 * depend on the implementation.
44 * isc_refcount_init(isc_refcount_t *ref, unsigned int n);
46 * Initialize the reference counter. There will be 'n' initial references.
54 * isc_refcount_destroy(isc_refcount_t *ref);
56 * Destroys a reference counter.
60 * The number of references is 0.
65 * isc_refcount_increment(isc_refcount_t *ref, unsigned int *targetp);
67 * Increments the reference count, returning the new value in targetp if it's
76 * isc_refcount_decrement(isc_refcount_t *ref, unsigned int *targetp);
78 * Decrements the reference count, returning the new value in targetp if it's
87 * Sample implementations
89 #ifdef ISC_PLATFORM_USETHREADS
91 typedef struct isc_refcount {
96 #define isc_refcount_init(rp, n) \
100 _r = isc_mutex_init(&(rp)->lock); \
101 RUNTIME_CHECK(_r == ISC_R_SUCCESS); \
104 #define isc_refcount_destroy(rp) \
106 REQUIRE((rp)->refs == 0); \
107 DESTROYLOCK(&(rp)->lock); \
110 #define isc_refcount_current(rp) ((unsigned int)((rp)->refs))
112 #define isc_refcount_increment(rp, tp) \
114 unsigned int *_tmp = (unsigned int *)(tp); \
116 REQUIRE((rp)->refs > 0); \
119 *_tmp = ((rp)->refs); \
120 UNLOCK(&(rp)->lock); \
123 #define isc_refcount_decrement(rp, tp) \
125 unsigned int *_tmp = (unsigned int *)(tp); \
127 REQUIRE((rp)->refs > 0); \
130 *_tmp = ((rp)->refs); \
131 UNLOCK(&(rp)->lock); \
136 typedef struct isc_refcount {
140 #define isc_refcount_init(rp, n) ((rp)->refs = (n))
141 #define isc_refcount_destroy(rp) (REQUIRE((rp)->refs == 0))
142 #define isc_refcount_current(rp) ((unsigned int)((rp)->refs))
144 #define isc_refcount_increment(rp, tp) \
146 unsigned int *_tmp = (unsigned int *)(tp); \
147 int _n = ++(rp)->refs; \
152 #define isc_refcount_decrement(rp, tp) \
154 unsigned int *_tmp = (unsigned int *)(tp); \
155 int _n = --(rp)->refs; \
164 #endif /* ISC_REFCOUNT_H */