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