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