blob: 3ddfc253801f906598b30eeeecf59c9088b10031 [file] [log] [blame]
bart8bba1f72008-02-27 16:13:05 +00001/** Initialize several kinds of mutexes and lock each mutex twice.
2 * Note: locking a regular mutex twice causes a deadlock.
bart5357fcb2008-02-27 15:46:00 +00003 */
4
5#define _GNU_SOURCE
6
7#include <stdio.h>
bart4240ff32008-02-27 17:41:22 +00008#include <unistd.h>
bart5357fcb2008-02-27 15:46:00 +00009#include <pthread.h>
bart85569572008-05-03 09:15:25 +000010#include "../../config.h"
bart5357fcb2008-02-27 15:46:00 +000011
bart4240ff32008-02-27 17:41:22 +000012
njnf76d27a2009-05-28 01:53:07 +000013#if !defined(VGO_darwin)
bart5357fcb2008-02-27 15:46:00 +000014static void lock_twice(pthread_mutex_t* const p)
15{
16 pthread_mutex_lock(p);
17 pthread_mutex_lock(p);
18 pthread_mutex_unlock(p);
19 pthread_mutex_unlock(p);
20}
njnf76d27a2009-05-28 01:53:07 +000021#endif
bart5357fcb2008-02-27 15:46:00 +000022
23int main(int argc, char** argv)
24{
bart8bba1f72008-02-27 16:13:05 +000025 /* Let the program abort after 3 seconds instead of leaving it deadlocked. */
26 alarm(3);
bart85569572008-05-03 09:15:25 +000027
28#if defined(HAVE_PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
bart5357fcb2008-02-27 15:46:00 +000029 {
30 pthread_mutex_t m = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
31
32 printf("Recursive mutex (statically initialized).\n");
33 lock_twice(&m);
bart68d80f42008-03-08 15:03:30 +000034 pthread_mutex_destroy(&m);
bart85569572008-05-03 09:15:25 +000035 }
36#endif
37#if defined(HAVE_PTHREAD_MUTEX_RECURSIVE_NP)
bart5357fcb2008-02-27 15:46:00 +000038 {
39 pthread_mutex_t m;
40 pthread_mutexattr_t attr;
41
42 printf("Recursive mutex (initialized via mutex attributes).\n");
43 pthread_mutexattr_init(&attr);
44 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
45 pthread_mutex_init(&m, &attr);
46 pthread_mutexattr_destroy(&attr);
47 lock_twice(&m);
48 pthread_mutex_destroy(&m);
bart85569572008-05-03 09:15:25 +000049 }
50#endif
51#if defined(HAVE_PTHREAD_MUTEX_ERRORCHECK_NP)
bart5357fcb2008-02-27 15:46:00 +000052 {
53 pthread_mutex_t m;
54 pthread_mutexattr_t attr;
55
56 printf("Error checking mutex.\n");
57 pthread_mutexattr_init(&attr);
58 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK_NP);
59 pthread_mutex_init(&m, &attr);
60 pthread_mutexattr_destroy(&attr);
61 lock_twice(&m);
bart85569572008-05-03 09:15:25 +000062 pthread_mutex_destroy(&m);
63 }
64#endif
njnf76d27a2009-05-28 01:53:07 +000065
66// DDD: Darwin doesn't support signals yet, so the alarm() call doesn't kick
67// in, which causes it to hang.
68#if !defined(VGO_darwin)
bart5357fcb2008-02-27 15:46:00 +000069 {
70 pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
71
72 printf("Non-recursive mutex.\n");
bart8bba1f72008-02-27 16:13:05 +000073 fflush(stdout);
bart5357fcb2008-02-27 15:46:00 +000074 lock_twice(&m);
bart85569572008-05-03 09:15:25 +000075 }
bart8bba1f72008-02-27 16:13:05 +000076 printf("Done.\n");
njnf76d27a2009-05-28 01:53:07 +000077#endif
bart5357fcb2008-02-27 15:46:00 +000078 return 0;
79}