util.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004-2007, 2010-2012  Internet Systems Consortium, Inc. ("ISC")
00003  * Copyright (C) 1998-2001  Internet Software Consortium.
00004  *
00005  * Permission to use, copy, modify, and/or distribute this software for any
00006  * purpose with or without fee is hereby granted, provided that the above
00007  * copyright notice and this permission notice appear in all copies.
00008  *
00009  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00010  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00011  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00012  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00013  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00014  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00015  * PERFORMANCE OF THIS SOFTWARE.
00016  */
00017 
00018 /* $Id$ */
00019 
00020 #ifndef ISC_UTIL_H
00021 #define ISC_UTIL_H 1
00022 
00023 /*! \file isc/util.h
00024  * NOTE:
00025  *
00026  * This file is not to be included from any <isc/???.h> (or other) library
00027  * files.
00028  *
00029  * \brief
00030  * Including this file puts several macros in your name space that are
00031  * not protected (as all the other ISC functions/macros do) by prepending
00032  * ISC_ or isc_ to the name.
00033  */
00034 
00035 /***
00036  *** General Macros.
00037  ***/
00038 
00039 /*%
00040  * Use this to hide unused function arguments.
00041  * \code
00042  * int
00043  * foo(char *bar)
00044  * {
00045  *      UNUSED(bar);
00046  * }
00047  * \endcode
00048  */
00049 #define UNUSED(x)      (void)(x)
00050 
00051 /*%
00052  * The opposite: silent warnings about stored values which are never read.
00053  */
00054 #define POST(x)        (void)(x)
00055 
00056 #define ISC_MAX(a, b)  ((a) > (b) ? (a) : (b))
00057 #define ISC_MIN(a, b)  ((a) < (b) ? (a) : (b))
00058 
00059 /*%
00060  * Use this to remove the const qualifier of a variable to assign it to
00061  * a non-const variable or pass it as a non-const function argument ...
00062  * but only when you are sure it won't then be changed!
00063  * This is necessary to sometimes shut up some compilers
00064  * (as with gcc -Wcast-qual) when there is just no other good way to avoid the
00065  * situation.
00066  */
00067 #define DE_CONST(konst, var) \
00068         do { \
00069                 union { const void *k; void *v; } _u; \
00070                 _u.k = konst; \
00071                 var = _u.v; \
00072         } while (0)
00073 
00074 /*%
00075  * Use this in translation units that would otherwise be empty, to
00076  * suppress compiler warnings.
00077  */
00078 #define EMPTY_TRANSLATION_UNIT static void isc__empty(void) { isc__empty(); }
00079 
00080 /*%
00081  * We use macros instead of calling the routines directly because
00082  * the capital letters make the locking stand out.
00083  * We RUNTIME_CHECK for success since in general there's no way
00084  * for us to continue if they fail.
00085  */
00086 
00087 #ifdef ISC_UTIL_TRACEON
00088 #define ISC_UTIL_TRACE(a) a
00089 #include <stdio.h>              /* Required for fprintf/stderr when tracing. */
00090 #include <isc/msgs.h>           /* Required for isc_msgcat when tracing. */
00091 #else
00092 #define ISC_UTIL_TRACE(a)
00093 #endif
00094 
00095 #include <isc/result.h>         /* Contractual promise. */
00096 
00097 #define LOCK(lp) do { \
00098         ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \
00099                                isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
00100                                               ISC_MSG_LOCKING, "LOCKING"), \
00101                                (lp), __FILE__, __LINE__)); \
00102         RUNTIME_CHECK(isc_mutex_lock((lp)) == ISC_R_SUCCESS); \
00103         ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \
00104                                isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
00105                                               ISC_MSG_LOCKED, "LOCKED"), \
00106                                (lp), __FILE__, __LINE__)); \
00107         } while (0)
00108 #define UNLOCK(lp) do { \
00109         RUNTIME_CHECK(isc_mutex_unlock((lp)) == ISC_R_SUCCESS); \
00110         ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \
00111                                isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
00112                                               ISC_MSG_UNLOCKED, "UNLOCKED"), \
00113                                (lp), __FILE__, __LINE__)); \
00114         } while (0)
00115 #define ISLOCKED(lp) (1)
00116 #define DESTROYLOCK(lp) \
00117         RUNTIME_CHECK(isc_mutex_destroy((lp)) == ISC_R_SUCCESS)
00118 
00119 
00120 #define BROADCAST(cvp) do { \
00121         ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \
00122                                isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
00123                                               ISC_MSG_BROADCAST, "BROADCAST"),\
00124                                (cvp), __FILE__, __LINE__)); \
00125         RUNTIME_CHECK(isc_condition_broadcast((cvp)) == ISC_R_SUCCESS); \
00126         } while (0)
00127 #define SIGNAL(cvp) do { \
00128         ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \
00129                                isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
00130                                               ISC_MSG_SIGNAL, "SIGNAL"), \
00131                                (cvp), __FILE__, __LINE__)); \
00132         RUNTIME_CHECK(isc_condition_signal((cvp)) == ISC_R_SUCCESS); \
00133         } while (0)
00134 #define WAIT(cvp, lp) do { \
00135         ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %p %s %d\n", \
00136                                isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
00137                                               ISC_MSG_UTILWAIT, "WAIT"), \
00138                                (cvp), \
00139                                isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
00140                                               ISC_MSG_LOCK, "LOCK"), \
00141                                (lp), __FILE__, __LINE__)); \
00142         RUNTIME_CHECK(isc_condition_wait((cvp), (lp)) == ISC_R_SUCCESS); \
00143         ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %p %s %d\n", \
00144                                isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
00145                                               ISC_MSG_WAITED, "WAITED"), \
00146                                (cvp), \
00147                                isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
00148                                               ISC_MSG_LOCKED, "LOCKED"), \
00149                                (lp), __FILE__, __LINE__)); \
00150         } while (0)
00151 
00152 /*
00153  * isc_condition_waituntil can return ISC_R_TIMEDOUT, so we
00154  * don't RUNTIME_CHECK the result.
00155  *
00156  *  XXX Also, can't really debug this then...
00157  */
00158 
00159 #define WAITUNTIL(cvp, lp, tp) \
00160         isc_condition_waituntil((cvp), (lp), (tp))
00161 
00162 #define RWLOCK(lp, t) do { \
00163         ISC_UTIL_TRACE(fprintf(stderr, "%s %p, %d %s %d\n", \
00164                                isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
00165                                               ISC_MSG_RWLOCK, "RWLOCK"), \
00166                                (lp), (t), __FILE__, __LINE__)); \
00167         RUNTIME_CHECK(isc_rwlock_lock((lp), (t)) == ISC_R_SUCCESS); \
00168         ISC_UTIL_TRACE(fprintf(stderr, "%s %p, %d %s %d\n", \
00169                                isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
00170                                               ISC_MSG_RWLOCKED, "RWLOCKED"), \
00171                                (lp), (t), __FILE__, __LINE__)); \
00172         } while (0)
00173 #define RWUNLOCK(lp, t) do { \
00174         ISC_UTIL_TRACE(fprintf(stderr, "%s %p, %d %s %d\n", \
00175                                isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
00176                                               ISC_MSG_RWUNLOCK, "RWUNLOCK"), \
00177                                (lp), (t), __FILE__, __LINE__)); \
00178         RUNTIME_CHECK(isc_rwlock_unlock((lp), (t)) == ISC_R_SUCCESS); \
00179         } while (0)
00180 
00181 #define DESTROYMUTEXBLOCK(bp, n) \
00182         RUNTIME_CHECK(isc_mutexblock_destroy((bp), (n)) == ISC_R_SUCCESS)
00183 
00184 /*
00185  * List Macros.
00186  */
00187 #include <isc/list.h>           /* Contractual promise. */
00188 
00189 #define LIST(type)                      ISC_LIST(type)
00190 #define INIT_LIST(type)                 ISC_LIST_INIT(type)
00191 #define LINK(type)                      ISC_LINK(type)
00192 #define INIT_LINK(elt, link)            ISC_LINK_INIT(elt, link)
00193 #define HEAD(list)                      ISC_LIST_HEAD(list)
00194 #define TAIL(list)                      ISC_LIST_TAIL(list)
00195 #define EMPTY(list)                     ISC_LIST_EMPTY(list)
00196 #define PREV(elt, link)                 ISC_LIST_PREV(elt, link)
00197 #define NEXT(elt, link)                 ISC_LIST_NEXT(elt, link)
00198 #define APPEND(list, elt, link)         ISC_LIST_APPEND(list, elt, link)
00199 #define PREPEND(list, elt, link)        ISC_LIST_PREPEND(list, elt, link)
00200 #define UNLINK(list, elt, link)         ISC_LIST_UNLINK(list, elt, link)
00201 #define ENQUEUE(list, elt, link)        ISC_LIST_APPEND(list, elt, link)
00202 #define DEQUEUE(list, elt, link)        ISC_LIST_UNLINK(list, elt, link)
00203 #define INSERTBEFORE(li, b, e, ln)      ISC_LIST_INSERTBEFORE(li, b, e, ln)
00204 #define INSERTAFTER(li, a, e, ln)       ISC_LIST_INSERTAFTER(li, a, e, ln)
00205 #define APPENDLIST(list1, list2, link)  ISC_LIST_APPENDLIST(list1, list2, link)
00206 
00207 /*
00208  * Assertions
00209  */
00210 #include <isc/assertions.h>     /* Contractual promise. */
00211 
00212 /*% Require Assertion */
00213 #define REQUIRE(e)                      ISC_REQUIRE(e)
00214 /*% Ensure Assertion */
00215 #define ENSURE(e)                       ISC_ENSURE(e)
00216 /*% Insist Assertion */
00217 #define INSIST(e)                       ISC_INSIST(e)
00218 /*% Invariant Assertion */
00219 #define INVARIANT(e)                    ISC_INVARIANT(e)
00220 
00221 /*
00222  * Errors
00223  */
00224 #include <isc/error.h>          /* Contractual promise. */
00225 
00226 /*% Unexpected Error */
00227 #define UNEXPECTED_ERROR                isc_error_unexpected
00228 /*% Fatal Error */
00229 #define FATAL_ERROR                     isc_error_fatal
00230 /*% Runtime Check */
00231 #define RUNTIME_CHECK(cond)             ISC_ERROR_RUNTIMECHECK(cond)
00232 
00233 /*%
00234  * Time
00235  */
00236 #define TIME_NOW(tp)    RUNTIME_CHECK(isc_time_now((tp)) == ISC_R_SUCCESS)
00237 
00238 #endif /* ISC_UTIL_H */

Generated on Tue Apr 28 17:41:04 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha