1258945Sroberto/* 2280849Scy * Copyright (C) 2004-2007, 2010-2012 Internet Systems Consortium, Inc. ("ISC") 3258945Sroberto * Copyright (C) 1998-2001 Internet Software Consortium. 4258945Sroberto * 5258945Sroberto * Permission to use, copy, modify, and/or distribute this software for any 6258945Sroberto * purpose with or without fee is hereby granted, provided that the above 7258945Sroberto * copyright notice and this permission notice appear in all copies. 8258945Sroberto * 9258945Sroberto * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10258945Sroberto * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11258945Sroberto * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12258945Sroberto * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13258945Sroberto * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14258945Sroberto * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15258945Sroberto * PERFORMANCE OF THIS SOFTWARE. 16258945Sroberto */ 17258945Sroberto 18280849Scy/* $Id$ */ 19258945Sroberto 20258945Sroberto#ifndef ISC_UTIL_H 21258945Sroberto#define ISC_UTIL_H 1 22258945Sroberto 23258945Sroberto/*! \file isc/util.h 24258945Sroberto * NOTE: 25258945Sroberto * 26258945Sroberto * This file is not to be included from any <isc/???.h> (or other) library 27258945Sroberto * files. 28258945Sroberto * 29258945Sroberto * \brief 30258945Sroberto * Including this file puts several macros in your name space that are 31258945Sroberto * not protected (as all the other ISC functions/macros do) by prepending 32258945Sroberto * ISC_ or isc_ to the name. 33258945Sroberto */ 34258945Sroberto 35258945Sroberto/*** 36258945Sroberto *** General Macros. 37258945Sroberto ***/ 38258945Sroberto 39258945Sroberto/*% 40258945Sroberto * Use this to hide unused function arguments. 41258945Sroberto * \code 42258945Sroberto * int 43258945Sroberto * foo(char *bar) 44258945Sroberto * { 45258945Sroberto * UNUSED(bar); 46258945Sroberto * } 47258945Sroberto * \endcode 48258945Sroberto */ 49258945Sroberto#define UNUSED(x) (void)(x) 50258945Sroberto 51280849Scy/*% 52280849Scy * The opposite: silent warnings about stored values which are never read. 53280849Scy */ 54280849Scy#define POST(x) (void)(x) 55280849Scy 56258945Sroberto#define ISC_MAX(a, b) ((a) > (b) ? (a) : (b)) 57258945Sroberto#define ISC_MIN(a, b) ((a) < (b) ? (a) : (b)) 58258945Sroberto 59258945Sroberto/*% 60258945Sroberto * Use this to remove the const qualifier of a variable to assign it to 61258945Sroberto * a non-const variable or pass it as a non-const function argument ... 62258945Sroberto * but only when you are sure it won't then be changed! 63258945Sroberto * This is necessary to sometimes shut up some compilers 64258945Sroberto * (as with gcc -Wcast-qual) when there is just no other good way to avoid the 65258945Sroberto * situation. 66258945Sroberto */ 67258945Sroberto#define DE_CONST(konst, var) \ 68258945Sroberto do { \ 69258945Sroberto union { const void *k; void *v; } _u; \ 70258945Sroberto _u.k = konst; \ 71258945Sroberto var = _u.v; \ 72258945Sroberto } while (0) 73258945Sroberto 74258945Sroberto/*% 75258945Sroberto * Use this in translation units that would otherwise be empty, to 76258945Sroberto * suppress compiler warnings. 77258945Sroberto */ 78280849Scy#define EMPTY_TRANSLATION_UNIT extern void exit(int); 79258945Sroberto 80258945Sroberto/*% 81258945Sroberto * We use macros instead of calling the routines directly because 82258945Sroberto * the capital letters make the locking stand out. 83258945Sroberto * We RUNTIME_CHECK for success since in general there's no way 84258945Sroberto * for us to continue if they fail. 85258945Sroberto */ 86258945Sroberto 87258945Sroberto#ifdef ISC_UTIL_TRACEON 88258945Sroberto#define ISC_UTIL_TRACE(a) a 89258945Sroberto#include <stdio.h> /* Required for fprintf/stderr when tracing. */ 90258945Sroberto#include <isc/msgs.h> /* Required for isc_msgcat when tracing. */ 91258945Sroberto#else 92258945Sroberto#define ISC_UTIL_TRACE(a) 93258945Sroberto#endif 94258945Sroberto 95258945Sroberto#include <isc/result.h> /* Contractual promise. */ 96258945Sroberto 97258945Sroberto#define LOCK(lp) do { \ 98258945Sroberto ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \ 99258945Sroberto isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 100258945Sroberto ISC_MSG_LOCKING, "LOCKING"), \ 101258945Sroberto (lp), __FILE__, __LINE__)); \ 102258945Sroberto RUNTIME_CHECK(isc_mutex_lock((lp)) == ISC_R_SUCCESS); \ 103258945Sroberto ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \ 104258945Sroberto isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 105258945Sroberto ISC_MSG_LOCKED, "LOCKED"), \ 106258945Sroberto (lp), __FILE__, __LINE__)); \ 107258945Sroberto } while (0) 108258945Sroberto#define UNLOCK(lp) do { \ 109258945Sroberto RUNTIME_CHECK(isc_mutex_unlock((lp)) == ISC_R_SUCCESS); \ 110258945Sroberto ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \ 111258945Sroberto isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 112258945Sroberto ISC_MSG_UNLOCKED, "UNLOCKED"), \ 113258945Sroberto (lp), __FILE__, __LINE__)); \ 114258945Sroberto } while (0) 115258945Sroberto#define ISLOCKED(lp) (1) 116258945Sroberto#define DESTROYLOCK(lp) \ 117258945Sroberto RUNTIME_CHECK(isc_mutex_destroy((lp)) == ISC_R_SUCCESS) 118258945Sroberto 119258945Sroberto 120258945Sroberto#define BROADCAST(cvp) do { \ 121258945Sroberto ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \ 122258945Sroberto isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 123258945Sroberto ISC_MSG_BROADCAST, "BROADCAST"),\ 124258945Sroberto (cvp), __FILE__, __LINE__)); \ 125258945Sroberto RUNTIME_CHECK(isc_condition_broadcast((cvp)) == ISC_R_SUCCESS); \ 126258945Sroberto } while (0) 127258945Sroberto#define SIGNAL(cvp) do { \ 128258945Sroberto ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \ 129258945Sroberto isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 130258945Sroberto ISC_MSG_SIGNAL, "SIGNAL"), \ 131258945Sroberto (cvp), __FILE__, __LINE__)); \ 132258945Sroberto RUNTIME_CHECK(isc_condition_signal((cvp)) == ISC_R_SUCCESS); \ 133258945Sroberto } while (0) 134258945Sroberto#define WAIT(cvp, lp) do { \ 135258945Sroberto ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %p %s %d\n", \ 136258945Sroberto isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 137258945Sroberto ISC_MSG_UTILWAIT, "WAIT"), \ 138258945Sroberto (cvp), \ 139258945Sroberto isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 140258945Sroberto ISC_MSG_LOCK, "LOCK"), \ 141258945Sroberto (lp), __FILE__, __LINE__)); \ 142258945Sroberto RUNTIME_CHECK(isc_condition_wait((cvp), (lp)) == ISC_R_SUCCESS); \ 143258945Sroberto ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %p %s %d\n", \ 144258945Sroberto isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 145258945Sroberto ISC_MSG_WAITED, "WAITED"), \ 146258945Sroberto (cvp), \ 147258945Sroberto isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 148258945Sroberto ISC_MSG_LOCKED, "LOCKED"), \ 149258945Sroberto (lp), __FILE__, __LINE__)); \ 150258945Sroberto } while (0) 151258945Sroberto 152258945Sroberto/* 153258945Sroberto * isc_condition_waituntil can return ISC_R_TIMEDOUT, so we 154258945Sroberto * don't RUNTIME_CHECK the result. 155258945Sroberto * 156258945Sroberto * XXX Also, can't really debug this then... 157258945Sroberto */ 158258945Sroberto 159258945Sroberto#define WAITUNTIL(cvp, lp, tp) \ 160258945Sroberto isc_condition_waituntil((cvp), (lp), (tp)) 161258945Sroberto 162258945Sroberto#define RWLOCK(lp, t) do { \ 163258945Sroberto ISC_UTIL_TRACE(fprintf(stderr, "%s %p, %d %s %d\n", \ 164258945Sroberto isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 165258945Sroberto ISC_MSG_RWLOCK, "RWLOCK"), \ 166258945Sroberto (lp), (t), __FILE__, __LINE__)); \ 167258945Sroberto RUNTIME_CHECK(isc_rwlock_lock((lp), (t)) == ISC_R_SUCCESS); \ 168258945Sroberto ISC_UTIL_TRACE(fprintf(stderr, "%s %p, %d %s %d\n", \ 169258945Sroberto isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 170258945Sroberto ISC_MSG_RWLOCKED, "RWLOCKED"), \ 171258945Sroberto (lp), (t), __FILE__, __LINE__)); \ 172258945Sroberto } while (0) 173258945Sroberto#define RWUNLOCK(lp, t) do { \ 174258945Sroberto ISC_UTIL_TRACE(fprintf(stderr, "%s %p, %d %s %d\n", \ 175258945Sroberto isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ 176258945Sroberto ISC_MSG_RWUNLOCK, "RWUNLOCK"), \ 177258945Sroberto (lp), (t), __FILE__, __LINE__)); \ 178258945Sroberto RUNTIME_CHECK(isc_rwlock_unlock((lp), (t)) == ISC_R_SUCCESS); \ 179258945Sroberto } while (0) 180258945Sroberto 181258945Sroberto#define DESTROYMUTEXBLOCK(bp, n) \ 182258945Sroberto RUNTIME_CHECK(isc_mutexblock_destroy((bp), (n)) == ISC_R_SUCCESS) 183258945Sroberto 184258945Sroberto/* 185258945Sroberto * List Macros. 186258945Sroberto */ 187258945Sroberto#include <isc/list.h> /* Contractual promise. */ 188258945Sroberto 189258945Sroberto#define LIST(type) ISC_LIST(type) 190258945Sroberto#define INIT_LIST(type) ISC_LIST_INIT(type) 191258945Sroberto#define LINK(type) ISC_LINK(type) 192258945Sroberto#define INIT_LINK(elt, link) ISC_LINK_INIT(elt, link) 193258945Sroberto#define HEAD(list) ISC_LIST_HEAD(list) 194258945Sroberto#define TAIL(list) ISC_LIST_TAIL(list) 195258945Sroberto#define EMPTY(list) ISC_LIST_EMPTY(list) 196258945Sroberto#define PREV(elt, link) ISC_LIST_PREV(elt, link) 197258945Sroberto#define NEXT(elt, link) ISC_LIST_NEXT(elt, link) 198258945Sroberto#define APPEND(list, elt, link) ISC_LIST_APPEND(list, elt, link) 199258945Sroberto#define PREPEND(list, elt, link) ISC_LIST_PREPEND(list, elt, link) 200258945Sroberto#define UNLINK(list, elt, link) ISC_LIST_UNLINK(list, elt, link) 201258945Sroberto#define ENQUEUE(list, elt, link) ISC_LIST_APPEND(list, elt, link) 202258945Sroberto#define DEQUEUE(list, elt, link) ISC_LIST_UNLINK(list, elt, link) 203258945Sroberto#define INSERTBEFORE(li, b, e, ln) ISC_LIST_INSERTBEFORE(li, b, e, ln) 204258945Sroberto#define INSERTAFTER(li, a, e, ln) ISC_LIST_INSERTAFTER(li, a, e, ln) 205258945Sroberto#define APPENDLIST(list1, list2, link) ISC_LIST_APPENDLIST(list1, list2, link) 206258945Sroberto 207258945Sroberto/* 208258945Sroberto * Assertions 209258945Sroberto */ 210258945Sroberto#include <isc/assertions.h> /* Contractual promise. */ 211258945Sroberto 212258945Sroberto/*% Require Assertion */ 213258945Sroberto#define REQUIRE(e) ISC_REQUIRE(e) 214258945Sroberto/*% Ensure Assertion */ 215258945Sroberto#define ENSURE(e) ISC_ENSURE(e) 216258945Sroberto/*% Insist Assertion */ 217258945Sroberto#define INSIST(e) ISC_INSIST(e) 218258945Sroberto/*% Invariant Assertion */ 219258945Sroberto#define INVARIANT(e) ISC_INVARIANT(e) 220258945Sroberto 221258945Sroberto/* 222258945Sroberto * Errors 223258945Sroberto */ 224258945Sroberto#include <isc/error.h> /* Contractual promise. */ 225258945Sroberto 226258945Sroberto/*% Unexpected Error */ 227258945Sroberto#define UNEXPECTED_ERROR isc_error_unexpected 228258945Sroberto/*% Fatal Error */ 229258945Sroberto#define FATAL_ERROR isc_error_fatal 230258945Sroberto/*% Runtime Check */ 231258945Sroberto#define RUNTIME_CHECK(cond) ISC_ERROR_RUNTIMECHECK(cond) 232258945Sroberto 233258945Sroberto/*% 234258945Sroberto * Time 235258945Sroberto */ 236258945Sroberto#define TIME_NOW(tp) RUNTIME_CHECK(isc_time_now((tp)) == ISC_R_SUCCESS) 237258945Sroberto 238258945Sroberto#endif /* ISC_UTIL_H */ 239