1290001Sglebius/* 2290001Sglebius * Copyright (C) 2004-2007, 2010-2012 Internet Systems Consortium, Inc. ("ISC") 3290001Sglebius * Copyright (C) 1998-2001 Internet Software Consortium. 4290001Sglebius * 5290001Sglebius * Permission to use, copy, modify, and/or distribute this software for any 6290001Sglebius * purpose with or without fee is hereby granted, provided that the above 7290001Sglebius * copyright notice and this permission notice appear in all copies. 8290001Sglebius * 9290001Sglebius * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10290001Sglebius * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11290001Sglebius * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12290001Sglebius * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13290001Sglebius * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14290001Sglebius * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15290001Sglebius * PERFORMANCE OF THIS SOFTWARE. 16290001Sglebius */ 17290001Sglebius 18290001Sglebius/* $Id$ */ 19290001Sglebius 20290001Sglebius#ifndef ISC_UTIL_H 21290001Sglebius#define ISC_UTIL_H 1 22290001Sglebius 23290001Sglebius/*! \file isc/util.h 24290001Sglebius * NOTE: 25290001Sglebius * 26290001Sglebius * This file is not to be included from any <isc/???.h> (or other) library 27290001Sglebius * files. 28290001Sglebius * 29290001Sglebius * \brief 30290001Sglebius * Including this file puts several macros in your name space that are 31290001Sglebius * not protected (as all the other ISC functions/macros do) by prepending 32290001Sglebius * ISC_ or isc_ to the name. 33290001Sglebius */ 34290001Sglebius 35290001Sglebius/*** 36290001Sglebius *** General Macros. 37290001Sglebius ***/ 38290001Sglebius 39290001Sglebius/*% 40290001Sglebius * Use this to hide unused function arguments. 41290001Sglebius * \code 42290001Sglebius * int 43290001Sglebius * foo(char *bar) 44290001Sglebius * { 45290001Sglebius * UNUSED(bar); 46290001Sglebius * } 47290001Sglebius * \endcode 48290001Sglebius */ 49290001Sglebius#define UNUSED(x) (void)(x) 50290001Sglebius 51290001Sglebius/*% 52290001Sglebius * The opposite: silent warnings about stored values which are never read. 53290001Sglebius */ 54290001Sglebius#define POST(x) (void)(x) 55290001Sglebius 56290001Sglebius#define ISC_MAX(a, b) ((a) > (b) ? (a) : (b)) 57290001Sglebius#define ISC_MIN(a, b) ((a) < (b) ? (a) : (b)) 58290001Sglebius 59290001Sglebius/*% 60290001Sglebius * Use this to remove the const qualifier of a variable to assign it to 61290001Sglebius * a non-const variable or pass it as a non-const function argument ... 62290001Sglebius * but only when you are sure it won't then be changed! 63290001Sglebius * This is necessary to sometimes shut up some compilers 64290001Sglebius * (as with gcc -Wcast-qual) when there is just no other good way to avoid the 65290001Sglebius * situation. 66290001Sglebius */ 67290001Sglebius#define DE_CONST(konst, var) \ 68290001Sglebius do { \ 69290001Sglebius union { const void *k; void *v; } _u; \ 70290001Sglebius _u.k = konst; \ 71290001Sglebius var = _u.v; \ 72290001Sglebius } while (0) 73290001Sglebius 74290001Sglebius/*% 75290001Sglebius * Use this in translation units that would otherwise be empty, to 76290001Sglebius * suppress compiler warnings. 77290001Sglebius */ 78290001Sglebius#define EMPTY_TRANSLATION_UNIT extern void exit(int); 79290001Sglebius 80290001Sglebius/*% 81290001Sglebius * We use macros instead of calling the routines directly because 82290001Sglebius * the capital letters make the locking stand out. 83290001Sglebius * We RUNTIME_CHECK for success since in general there's no way 84290001Sglebius * for us to continue if they fail. 85290001Sglebius */ 86290001Sglebius 87290001Sglebius#ifdef ISC_UTIL_TRACEON 88290001Sglebius#define ISC_UTIL_TRACE(a) a 89290001Sglebius#include <stdio.h> /* Required for fprintf/stderr when tracing. */ 90290001Sglebius#include <isc/msgs.h> /* Required for isc_msgcat when tracing. */ 91290001Sglebius#else 92290001Sglebius#define ISC_UTIL_TRACE(a) 93290001Sglebius#endif 94290001Sglebius 95290001Sglebius#include <isc/result.h> /* Contractual promise. */ 96290001Sglebius 97290001Sglebius#define LOCK(lp) do { \ 98290001Sglebius ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \ 99290001Sglebius isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 100290001Sglebius ISC_MSG_LOCKING, "LOCKING"), \ 101290001Sglebius (lp), __FILE__, __LINE__)); \ 102290001Sglebius RUNTIME_CHECK(isc_mutex_lock((lp)) == ISC_R_SUCCESS); \ 103290001Sglebius ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \ 104290001Sglebius isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 105290001Sglebius ISC_MSG_LOCKED, "LOCKED"), \ 106290001Sglebius (lp), __FILE__, __LINE__)); \ 107290001Sglebius } while (0) 108290001Sglebius#define UNLOCK(lp) do { \ 109290001Sglebius RUNTIME_CHECK(isc_mutex_unlock((lp)) == ISC_R_SUCCESS); \ 110290001Sglebius ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \ 111290001Sglebius isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 112290001Sglebius ISC_MSG_UNLOCKED, "UNLOCKED"), \ 113290001Sglebius (lp), __FILE__, __LINE__)); \ 114290001Sglebius } while (0) 115290001Sglebius#define ISLOCKED(lp) (1) 116290001Sglebius#define DESTROYLOCK(lp) \ 117290001Sglebius RUNTIME_CHECK(isc_mutex_destroy((lp)) == ISC_R_SUCCESS) 118290001Sglebius 119290001Sglebius 120290001Sglebius#define BROADCAST(cvp) do { \ 121290001Sglebius ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \ 122290001Sglebius isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 123290001Sglebius ISC_MSG_BROADCAST, "BROADCAST"),\ 124290001Sglebius (cvp), __FILE__, __LINE__)); \ 125290001Sglebius RUNTIME_CHECK(isc_condition_broadcast((cvp)) == ISC_R_SUCCESS); \ 126290001Sglebius } while (0) 127290001Sglebius#define SIGNAL(cvp) do { \ 128290001Sglebius ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \ 129290001Sglebius isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 130290001Sglebius ISC_MSG_SIGNAL, "SIGNAL"), \ 131290001Sglebius (cvp), __FILE__, __LINE__)); \ 132290001Sglebius RUNTIME_CHECK(isc_condition_signal((cvp)) == ISC_R_SUCCESS); \ 133290001Sglebius } while (0) 134290001Sglebius#define WAIT(cvp, lp) do { \ 135290001Sglebius ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %p %s %d\n", \ 136290001Sglebius isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 137290001Sglebius ISC_MSG_UTILWAIT, "WAIT"), \ 138290001Sglebius (cvp), \ 139290001Sglebius isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 140290001Sglebius ISC_MSG_LOCK, "LOCK"), \ 141290001Sglebius (lp), __FILE__, __LINE__)); \ 142290001Sglebius RUNTIME_CHECK(isc_condition_wait((cvp), (lp)) == ISC_R_SUCCESS); \ 143290001Sglebius ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %p %s %d\n", \ 144290001Sglebius isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 145290001Sglebius ISC_MSG_WAITED, "WAITED"), \ 146290001Sglebius (cvp), \ 147290001Sglebius isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 148290001Sglebius ISC_MSG_LOCKED, "LOCKED"), \ 149290001Sglebius (lp), __FILE__, __LINE__)); \ 150290001Sglebius } while (0) 151290001Sglebius 152290001Sglebius/* 153290001Sglebius * isc_condition_waituntil can return ISC_R_TIMEDOUT, so we 154290001Sglebius * don't RUNTIME_CHECK the result. 155290001Sglebius * 156290001Sglebius * XXX Also, can't really debug this then... 157290001Sglebius */ 158290001Sglebius 159290001Sglebius#define WAITUNTIL(cvp, lp, tp) \ 160290001Sglebius isc_condition_waituntil((cvp), (lp), (tp)) 161290001Sglebius 162290001Sglebius#define RWLOCK(lp, t) do { \ 163290001Sglebius ISC_UTIL_TRACE(fprintf(stderr, "%s %p, %d %s %d\n", \ 164290001Sglebius isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 165290001Sglebius ISC_MSG_RWLOCK, "RWLOCK"), \ 166290001Sglebius (lp), (t), __FILE__, __LINE__)); \ 167290001Sglebius RUNTIME_CHECK(isc_rwlock_lock((lp), (t)) == ISC_R_SUCCESS); \ 168290001Sglebius ISC_UTIL_TRACE(fprintf(stderr, "%s %p, %d %s %d\n", \ 169290001Sglebius isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 170290001Sglebius ISC_MSG_RWLOCKED, "RWLOCKED"), \ 171290001Sglebius (lp), (t), __FILE__, __LINE__)); \ 172290001Sglebius } while (0) 173290001Sglebius#define RWUNLOCK(lp, t) do { \ 174290001Sglebius ISC_UTIL_TRACE(fprintf(stderr, "%s %p, %d %s %d\n", \ 175290001Sglebius isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 176290001Sglebius ISC_MSG_RWUNLOCK, "RWUNLOCK"), \ 177290001Sglebius (lp), (t), __FILE__, __LINE__)); \ 178290001Sglebius RUNTIME_CHECK(isc_rwlock_unlock((lp), (t)) == ISC_R_SUCCESS); \ 179290001Sglebius } while (0) 180290001Sglebius 181290001Sglebius#define DESTROYMUTEXBLOCK(bp, n) \ 182290001Sglebius RUNTIME_CHECK(isc_mutexblock_destroy((bp), (n)) == ISC_R_SUCCESS) 183290001Sglebius 184290001Sglebius/* 185290001Sglebius * List Macros. 186290001Sglebius */ 187290001Sglebius#include <isc/list.h> /* Contractual promise. */ 188290001Sglebius 189290001Sglebius#define LIST(type) ISC_LIST(type) 190290001Sglebius#define INIT_LIST(type) ISC_LIST_INIT(type) 191290001Sglebius#define LINK(type) ISC_LINK(type) 192290001Sglebius#define INIT_LINK(elt, link) ISC_LINK_INIT(elt, link) 193290001Sglebius#define HEAD(list) ISC_LIST_HEAD(list) 194290001Sglebius#define TAIL(list) ISC_LIST_TAIL(list) 195290001Sglebius#define EMPTY(list) ISC_LIST_EMPTY(list) 196290001Sglebius#define PREV(elt, link) ISC_LIST_PREV(elt, link) 197290001Sglebius#define NEXT(elt, link) ISC_LIST_NEXT(elt, link) 198290001Sglebius#define APPEND(list, elt, link) ISC_LIST_APPEND(list, elt, link) 199290001Sglebius#define PREPEND(list, elt, link) ISC_LIST_PREPEND(list, elt, link) 200290001Sglebius#define UNLINK(list, elt, link) ISC_LIST_UNLINK(list, elt, link) 201290001Sglebius#define ENQUEUE(list, elt, link) ISC_LIST_APPEND(list, elt, link) 202290001Sglebius#define DEQUEUE(list, elt, link) ISC_LIST_UNLINK(list, elt, link) 203290001Sglebius#define INSERTBEFORE(li, b, e, ln) ISC_LIST_INSERTBEFORE(li, b, e, ln) 204290001Sglebius#define INSERTAFTER(li, a, e, ln) ISC_LIST_INSERTAFTER(li, a, e, ln) 205290001Sglebius#define APPENDLIST(list1, list2, link) ISC_LIST_APPENDLIST(list1, list2, link) 206290001Sglebius 207290001Sglebius/* 208290001Sglebius * Assertions 209290001Sglebius */ 210290001Sglebius#include <isc/assertions.h> /* Contractual promise. */ 211290001Sglebius 212290001Sglebius/*% Require Assertion */ 213290001Sglebius#define REQUIRE(e) ISC_REQUIRE(e) 214290001Sglebius/*% Ensure Assertion */ 215290001Sglebius#define ENSURE(e) ISC_ENSURE(e) 216290001Sglebius/*% Insist Assertion */ 217290001Sglebius#define INSIST(e) ISC_INSIST(e) 218290001Sglebius/*% Invariant Assertion */ 219290001Sglebius#define INVARIANT(e) ISC_INVARIANT(e) 220290001Sglebius 221290001Sglebius/* 222290001Sglebius * Errors 223290001Sglebius */ 224290001Sglebius#include <isc/error.h> /* Contractual promise. */ 225290001Sglebius 226290001Sglebius/*% Unexpected Error */ 227290001Sglebius#define UNEXPECTED_ERROR isc_error_unexpected 228290001Sglebius/*% Fatal Error */ 229290001Sglebius#define FATAL_ERROR isc_error_fatal 230290001Sglebius/*% Runtime Check */ 231290001Sglebius#define RUNTIME_CHECK(cond) ISC_ERROR_RUNTIMECHECK(cond) 232290001Sglebius 233290001Sglebius/*% 234290001Sglebius * Time 235290001Sglebius */ 236290001Sglebius#define TIME_NOW(tp) RUNTIME_CHECK(isc_time_now((tp)) == ISC_R_SUCCESS) 237290001Sglebius 238290001Sglebius#endif /* ISC_UTIL_H */ 239