1 /* 2 * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (C) 1998-2002 Internet Software Consortium. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 * PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 /* $Id: mutex.h,v 1.30 2007/06/19 23:47:18 tbox Exp $ */ 19 20 #ifndef ISC_MUTEX_H 21 #define ISC_MUTEX_H 1 22 23 /*! \file */ 24 25 #include <pthread.h> 26 #include <stdio.h> 27 28 #include <isc/lang.h> 29 #include <isc/result.h> /* for ISC_R_ codes */ 30 31 ISC_LANG_BEGINDECLS 32 33 /*! 34 * Supply mutex attributes that enable deadlock detection 35 * (helpful when debugging). This is system dependent and 36 * currently only supported on NetBSD. 37 */ 38 #if ISC_MUTEX_DEBUG && defined(__NetBSD__) && defined(PTHREAD_MUTEX_ERRORCHECK) 39 extern pthread_mutexattr_t isc__mutex_attrs; 40 #define ISC__MUTEX_ATTRS &isc__mutex_attrs 41 #else 42 #define ISC__MUTEX_ATTRS NULL 43 #endif 44 45 /* XXX We could do fancier error handling... */ 46 47 /*! 48 * Define ISC_MUTEX_PROFILE to turn on profiling of mutexes by line. When 49 * enabled, isc_mutex_stats() can be used to print a table showing the 50 * number of times each type of mutex was locked and the amount of time 51 * waiting to obtain the lock. 52 */ 53 #ifndef ISC_MUTEX_PROFILE 54 #define ISC_MUTEX_PROFILE 0 55 #endif 56 57 #if ISC_MUTEX_PROFILE 58 typedef struct isc_mutexstats isc_mutexstats_t; 59 60 typedef struct { 61 pthread_mutex_t mutex; /*%< The actual mutex. */ 62 isc_mutexstats_t * stats; /*%< Mutex statistics. */ 63 } isc_mutex_t; 64 #else 65 typedef pthread_mutex_t isc_mutex_t; 66 #endif 67 68 69 #if ISC_MUTEX_PROFILE 70 #define isc_mutex_init(mp) \ 71 isc_mutex_init_profile((mp), __FILE__, __LINE__) 72 #else 73 #if ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK) 74 #define isc_mutex_init(mp) \ 75 isc_mutex_init_errcheck((mp)) 76 #else 77 #define isc_mutex_init(mp) \ 78 isc__mutex_init((mp), __FILE__, __LINE__) 79 isc_result_t isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int line); 80 #endif 81 #endif 82 83 #if ISC_MUTEX_PROFILE 84 #define isc_mutex_lock(mp) \ 85 isc_mutex_lock_profile((mp), __FILE__, __LINE__) 86 #else 87 #define isc_mutex_lock(mp) \ 88 ((pthread_mutex_lock((mp)) == 0) ? \ 89 ISC_R_SUCCESS : ISC_R_UNEXPECTED) 90 #endif 91 92 #if ISC_MUTEX_PROFILE 93 #define isc_mutex_unlock(mp) \ 94 isc_mutex_unlock_profile((mp), __FILE__, __LINE__) 95 #else 96 #define isc_mutex_unlock(mp) \ 97 ((pthread_mutex_unlock((mp)) == 0) ? \ 98 ISC_R_SUCCESS : ISC_R_UNEXPECTED) 99 #endif 100 101 #if ISC_MUTEX_PROFILE 102 #define isc_mutex_trylock(mp) \ 103 ((pthread_mutex_trylock((&(mp)->mutex)) == 0) ? \ 104 ISC_R_SUCCESS : ISC_R_LOCKBUSY) 105 #else 106 #define isc_mutex_trylock(mp) \ 107 ((pthread_mutex_trylock((mp)) == 0) ? \ 108 ISC_R_SUCCESS : ISC_R_LOCKBUSY) 109 #endif 110 111 #if ISC_MUTEX_PROFILE 112 #define isc_mutex_destroy(mp) \ 113 ((pthread_mutex_destroy((&(mp)->mutex)) == 0) ? \ 114 ISC_R_SUCCESS : ISC_R_UNEXPECTED) 115 #else 116 #define isc_mutex_destroy(mp) \ 117 ((pthread_mutex_destroy((mp)) == 0) ? \ 118 ISC_R_SUCCESS : ISC_R_UNEXPECTED) 119 #endif 120 121 #if ISC_MUTEX_PROFILE 122 #define isc_mutex_stats(fp) isc_mutex_statsprofile(fp); 123 #else 124 #define isc_mutex_stats(fp) 125 #endif 126 127 #if ISC_MUTEX_PROFILE 128 129 isc_result_t 130 isc_mutex_init_profile(isc_mutex_t *mp, const char * _file, int _line); 131 isc_result_t 132 isc_mutex_lock_profile(isc_mutex_t *mp, const char * _file, int _line); 133 isc_result_t 134 isc_mutex_unlock_profile(isc_mutex_t *mp, const char * _file, int _line); 135 136 void 137 isc_mutex_statsprofile(FILE *fp); 138 139 isc_result_t 140 isc_mutex_init_errcheck(isc_mutex_t *mp); 141 142 #endif /* ISC_MUTEX_PROFILE */ 143 144 ISC_LANG_ENDDECLS 145 #endif /* ISC_MUTEX_H */ 146