1 /* 2 * Copyright © 2016 Mozilla Foundation 3 * 4 * This program is made available under an ISC-style license. See the 5 * accompanying file LICENSE for details. 6 */ 7 8 #if !defined(CUBEB_UTILS_UNIX) 9 #define CUBEB_UTILS_UNIX 10 11 #include <errno.h> 12 #include <pthread.h> 13 #include <stdio.h> 14 15 /* This wraps a critical section to track the owner in debug mode. */ 16 class owned_critical_section { 17 public: owned_critical_section()18 owned_critical_section() 19 { 20 pthread_mutexattr_t attr; 21 pthread_mutexattr_init(&attr); 22 #ifndef NDEBUG 23 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); 24 #else 25 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); 26 #endif 27 28 #ifndef NDEBUG 29 int r = 30 #endif 31 pthread_mutex_init(&mutex, &attr); 32 #ifndef NDEBUG 33 assert(r == 0); 34 #endif 35 36 pthread_mutexattr_destroy(&attr); 37 } 38 ~owned_critical_section()39 ~owned_critical_section() 40 { 41 #ifndef NDEBUG 42 int r = 43 #endif 44 pthread_mutex_destroy(&mutex); 45 #ifndef NDEBUG 46 assert(r == 0); 47 #endif 48 } 49 lock()50 void lock() 51 { 52 #ifndef NDEBUG 53 int r = 54 #endif 55 pthread_mutex_lock(&mutex); 56 #ifndef NDEBUG 57 assert(r == 0 && "Deadlock"); 58 #endif 59 } 60 unlock()61 void unlock() 62 { 63 #ifndef NDEBUG 64 int r = 65 #endif 66 pthread_mutex_unlock(&mutex); 67 #ifndef NDEBUG 68 assert(r == 0 && "Unlocking unlocked mutex"); 69 #endif 70 } 71 assert_current_thread_owns()72 void assert_current_thread_owns() 73 { 74 #ifndef NDEBUG 75 int r = pthread_mutex_lock(&mutex); 76 assert(r == EDEADLK); 77 #endif 78 } 79 80 private: 81 pthread_mutex_t mutex; 82 83 // Disallow copy and assignment because pthread_mutex_t cannot be copied. 84 owned_critical_section(const owned_critical_section &); 85 owned_critical_section & operator=(const owned_critical_section &); 86 }; 87 88 #endif /* CUBEB_UTILS_UNIX */ 89