1 /* 2 * Copyright (C) 1998-2001 Internet Software Consortium. 3 * 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM 9 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL 10 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL 11 * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, 12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING 13 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 14 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 15 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 /* $Id: util.h,v 1.23 2001/11/30 01:59:38 gson Exp $ */ 19 20 #ifndef ISC_UTIL_H 21 #define ISC_UTIL_H 1 22 23 /* 24 * NOTE: 25 * 26 * This file is not to be included from any <isc/???.h> (or other) library 27 * files. 28 * 29 * Including this file puts several macros in your name space that are 30 * not protected (as all the other ISC functions/macros do) by prepending 31 * ISC_ or isc_ to the name. 32 */ 33 34 /*** 35 *** General Macros. 36 ***/ 37 38 /* 39 * Use this to hide unused function arguments. 40 * 41 * int 42 * foo(char *bar) 43 * { 44 * UNUSED(bar); 45 * } 46 */ 47 #define UNUSED(x) (void)(x) 48 49 #define ISC_MAX(a, b) ((a) > (b) ? (a) : (b)) 50 #define ISC_MIN(a, b) ((a) < (b) ? (a) : (b)) 51 52 /* 53 * Use this to remove the const qualifier of a variable to assign it to 54 * a non-const variable or pass it as a non-const function argument ... 55 * but only when you are sure it won't then be changed! 56 * This is necessary to sometimes shut up some compilers 57 * (as with gcc -Wcast-qual) when there is just no other good way to avoid the 58 * situation. 59 */ 60 #define DE_CONST(konst, var) \ 61 do { \ 62 union { const void *k; void *v; } _u; \ 63 _u.k = konst; \ 64 var = _u.v; \ 65 } while (0) 66 67 /* 68 * Use this in translation units that would otherwise be empty, to 69 * suppress compiler warnings. 70 */ 71 #define EMPTY_TRANSLATION_UNIT static void isc__empty(void) { isc__empty(); } 72 73 /* 74 * We use macros instead of calling the routines directly because 75 * the capital letters make the locking stand out. 76 * 77 * We RUNTIME_CHECK for success since in general there's no way 78 * for us to continue if they fail. 79 */ 80 81 #ifdef ISC_UTIL_TRACEON 82 #define ISC_UTIL_TRACE(a) a 83 #include <stdio.h> /* Required for fprintf/stderr when tracing. */ 84 #include <isc/msgs.h> /* Required for isc_msgcat when tracing. */ 85 #else 86 #define ISC_UTIL_TRACE(a) 87 #endif 88 89 #include <isc/result.h> /* Contractual promise. */ 90 91 #define LOCK(lp) do { \ 92 ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \ 93 isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 94 ISC_MSG_LOCKING, "LOCKING"), \ 95 (lp), __FILE__, __LINE__)); \ 96 RUNTIME_CHECK(isc_mutex_lock((lp)) == ISC_R_SUCCESS); \ 97 ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \ 98 isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 99 ISC_MSG_LOCKED, "LOCKED"), \ 100 (lp), __FILE__, __LINE__)); \ 101 } while (0) 102 #define UNLOCK(lp) do { \ 103 RUNTIME_CHECK(isc_mutex_unlock((lp)) == ISC_R_SUCCESS); \ 104 ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \ 105 isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 106 ISC_MSG_UNLOCKED, "UNLOCKED"), \ 107 (lp), __FILE__, __LINE__)); \ 108 } while (0) 109 #define ISLOCKED(lp) (1) 110 #define DESTROYLOCK(lp) \ 111 RUNTIME_CHECK(isc_mutex_destroy((lp)) == ISC_R_SUCCESS) 112 113 114 #define BROADCAST(cvp) do { \ 115 ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \ 116 isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 117 ISC_MSG_BROADCAST, "BROADCAST"),\ 118 (cvp), __FILE__, __LINE__)); \ 119 RUNTIME_CHECK(isc_condition_broadcast((cvp)) == ISC_R_SUCCESS); \ 120 } while (0) 121 #define SIGNAL(cvp) do { \ 122 ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \ 123 isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 124 ISC_MSG_SIGNAL, "SIGNAL"), \ 125 (cvp), __FILE__, __LINE__)); \ 126 RUNTIME_CHECK(isc_condition_signal((cvp)) == ISC_R_SUCCESS); \ 127 } while (0) 128 #define WAIT(cvp, lp) do { \ 129 ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %p %s %d\n", \ 130 isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 131 ISC_MSG_UTILWAIT, "WAIT"), \ 132 (cvp), \ 133 isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 134 ISC_MSG_LOCK, "LOCK"), \ 135 (lp), __FILE__, __LINE__)); \ 136 RUNTIME_CHECK(isc_condition_wait((cvp), (lp)) == ISC_R_SUCCESS); \ 137 ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %p %s %d\n", \ 138 isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 139 ISC_MSG_WAITED, "WAITED"), \ 140 (cvp), \ 141 isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 142 ISC_MSG_LOCKED, "LOCKED"), \ 143 (lp), __FILE__, __LINE__)); \ 144 } while (0) 145 146 /* 147 * isc_condition_waituntil can return ISC_R_TIMEDOUT, so we 148 * don't RUNTIME_CHECK the result. 149 * 150 * XXX Also, can't really debug this then... 151 */ 152 153 #define WAITUNTIL(cvp, lp, tp) \ 154 isc_condition_waituntil((cvp), (lp), (tp)) 155 156 #define RWLOCK(lp, t) do { \ 157 ISC_UTIL_TRACE(fprintf(stderr, "%s %p, %d %s %d\n", \ 158 isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 159 ISC_MSG_RWLOCK, "RWLOCK"), \ 160 (lp), (t), __FILE__, __LINE__)); \ 161 RUNTIME_CHECK(isc_rwlock_lock((lp), (t)) == ISC_R_SUCCESS); \ 162 ISC_UTIL_TRACE(fprintf(stderr, "%s %p, %d %s %d\n", \ 163 isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 164 ISC_MSG_RWLOCKED, "RWLOCKED"), \ 165 (lp), (t), __FILE__, __LINE__)); \ 166 } while (0) 167 #define RWUNLOCK(lp, t) do { \ 168 ISC_UTIL_TRACE(fprintf(stderr, "%s %p, %d %s %d\n", \ 169 isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 170 ISC_MSG_RWUNLOCK, "RWUNLOCK"), \ 171 (lp), (t), __FILE__, __LINE__)); \ 172 RUNTIME_CHECK(isc_rwlock_unlock((lp), (t)) == ISC_R_SUCCESS); \ 173 } while (0) 174 175 #define DESTROYMUTEXBLOCK(bp, n) \ 176 RUNTIME_CHECK(isc_mutexblock_destroy((bp), (n)) == ISC_R_SUCCESS) 177 178 /* 179 * List Macros. 180 */ 181 #include <isc/list.h> /* Contractual promise. */ 182 183 #define LIST(type) ISC_LIST(type) 184 #define INIT_LIST(type) ISC_LIST_INIT(type) 185 #define LINK(type) ISC_LINK(type) 186 #define INIT_LINK(elt, link) ISC_LINK_INIT(elt, link) 187 #define HEAD(list) ISC_LIST_HEAD(list) 188 #define TAIL(list) ISC_LIST_TAIL(list) 189 #define EMPTY(list) ISC_LIST_EMPTY(list) 190 #define PREV(elt, link) ISC_LIST_PREV(elt, link) 191 #define NEXT(elt, link) ISC_LIST_NEXT(elt, link) 192 #define APPEND(list, elt, link) ISC_LIST_APPEND(list, elt, link) 193 #define PREPEND(list, elt, link) ISC_LIST_PREPEND(list, elt, link) 194 #define UNLINK(list, elt, link) ISC_LIST_UNLINK(list, elt, link) 195 #define ENQUEUE(list, elt, link) ISC_LIST_APPEND(list, elt, link) 196 #define DEQUEUE(list, elt, link) ISC_LIST_UNLINK(list, elt, link) 197 #define INSERTBEFORE(li, b, e, ln) ISC_LIST_INSERTBEFORE(li, b, e, ln) 198 #define INSERTAFTER(li, a, e, ln) ISC_LIST_INSERTAFTER(li, a, e, ln) 199 #define APPENDLIST(list1, list2, link) ISC_LIST_APPENDLIST(list1, list2, link) 200 201 /* 202 * Assertions 203 */ 204 #include <isc/assertions.h> /* Contractual promise. */ 205 206 #define REQUIRE(e) ISC_REQUIRE(e) 207 #define ENSURE(e) ISC_ENSURE(e) 208 #define INSIST(e) ISC_INSIST(e) 209 #define INVARIANT(e) ISC_INVARIANT(e) 210 211 /* 212 * Errors 213 */ 214 #include <isc/error.h> /* Contractual promise. */ 215 216 #define UNEXPECTED_ERROR isc_error_unexpected 217 #define FATAL_ERROR isc_error_fatal 218 #define RUNTIME_CHECK(cond) ISC_ERROR_RUNTIMECHECK(cond) 219 220 /* 221 * Time 222 */ 223 #define TIME_NOW(tp) RUNTIME_CHECK(isc_time_now((tp)) == ISC_R_SUCCESS) 224 225 #endif /* ISC_UTIL_H */ 226