1 /** Initialize several kinds of mutexes and lock each mutex twice. 2 * Note: locking a regular mutex twice causes a deadlock. 3 */ 4 5 #define _GNU_SOURCE 6 7 #include <stdio.h> 8 #include <unistd.h> 9 #include <pthread.h> 10 #include "../../config.h" 11 12 13 static void lock_twice(pthread_mutex_t* const p) 14 { 15 if (pthread_mutex_trylock(p) != 0) 16 fprintf(stderr, "first lock call failed !\n"); 17 if (pthread_mutex_trylock(p) != 0) 18 fprintf(stderr, "second lock call failed !\n"); 19 if (pthread_mutex_unlock(p) != 0) 20 fprintf(stderr, "first unlock call failed !\n"); 21 if (pthread_mutex_unlock(p) != 0) 22 fprintf(stderr, "second unlock call failed !\n"); 23 } 24 25 int main(int argc, char** argv) 26 { 27 #if defined(HAVE_PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) 28 { 29 pthread_mutex_t m = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; 30 31 fprintf(stderr, "Recursive mutex (statically initialized).\n"); 32 lock_twice(&m); 33 pthread_mutex_destroy(&m); 34 } 35 #endif 36 #if defined(HAVE_PTHREAD_MUTEX_RECURSIVE_NP) 37 { 38 pthread_mutex_t m; 39 pthread_mutexattr_t attr; 40 41 fprintf(stderr, "\nRecursive mutex (initialized via mutex attributes).\n"); 42 pthread_mutexattr_init(&attr); 43 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP); 44 pthread_mutex_init(&m, &attr); 45 pthread_mutexattr_destroy(&attr); 46 lock_twice(&m); 47 pthread_mutex_destroy(&m); 48 } 49 #endif 50 #if defined(HAVE_PTHREAD_MUTEX_ERRORCHECK_NP) 51 { 52 pthread_mutex_t m; 53 pthread_mutexattr_t attr; 54 55 fprintf(stderr, "\nError checking mutex.\n"); 56 pthread_mutexattr_init(&attr); 57 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK_NP); 58 pthread_mutex_init(&m, &attr); 59 pthread_mutexattr_destroy(&attr); 60 lock_twice(&m); 61 pthread_mutex_destroy(&m); 62 } 63 #endif 64 65 { 66 pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; 67 68 fprintf(stderr, "\nNon-recursive mutex.\n"); 69 lock_twice(&m); 70 } 71 72 fprintf(stderr, "\nDone.\n"); 73 74 return 0; 75 } 76