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 31ISC_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) 39extern 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 58typedef struct isc_mutexstats isc_mutexstats_t; 59 60typedef struct { 61 pthread_mutex_t mutex; /*%< The actual mutex. */ 62 isc_mutexstats_t * stats; /*%< Mutex statistics. */ 63} isc_mutex_t; 64#else 65typedef 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__) 79isc_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 129isc_result_t 130isc_mutex_init_profile(isc_mutex_t *mp, const char * _file, int _line); 131isc_result_t 132isc_mutex_lock_profile(isc_mutex_t *mp, const char * _file, int _line); 133isc_result_t 134isc_mutex_unlock_profile(isc_mutex_t *mp, const char * _file, int _line); 135 136void 137isc_mutex_statsprofile(FILE *fp); 138 139isc_result_t 140isc_mutex_init_errcheck(isc_mutex_t *mp); 141 142#endif /* ISC_MUTEX_PROFILE */ 143 144ISC_LANG_ENDDECLS 145#endif /* ISC_MUTEX_H */ 146