1//////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
4// Software License, Version 1.0. (See accompanying file
5// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7// See http://www.boost.org/libs/interprocess for documentation.
8//
9//////////////////////////////////////////////////////////////////////////////
10
11#include <boost/interprocess/detail/workaround.hpp>
12
13//Robust mutex handling is only supported in conforming POSIX systems
14#if !defined(BOOST_INTERPROCESS_POSIX_PROCESS_SHARED) || !defined(BOOST_INTERPROCESS_POSIX_ROBUST_MUTEXES)
15
16int main()
17{
18 return 0;
19}
20
21#else
22
23#include <boost/interprocess/detail/os_thread_functions.hpp>
24
25#include <boost/interprocess/sync/interprocess_mutex.hpp>
26#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
27#include "mutex_test_template.hpp"
28#include <iostream>
29
30
31namespace boost {
32namespace interprocess {
33namespace test {
34
35template<typename M>
36void lock_and_exit(void *, M &sm)
37{
38 sm.lock();
39}
40
41enum EOwnerDeadLockType
42{
43 OwnerDeadLock,
44 OwnerDeadTryLock,
45 OwnerDeadTimedLock
46};
47
48template<class M>
49void test_owner_dead_mutex_do_lock(M &mtx, EOwnerDeadLockType lock_type)
50{
51 switch (lock_type)
52 {
53 case OwnerDeadLock:
54 mtx.lock();
55 break;
56
57 case OwnerDeadTryLock:
58 mtx.try_lock();
59 break;
60
61 case OwnerDeadTimedLock:
62 mtx.timed_lock(boost_systemclock_delay_ms(msecs: 10));
63 break;
64 }
65}
66
67template<class M>
68int test_owner_dead_mutex_impl(EOwnerDeadLockType lock_type)
69{
70 using namespace boost::interprocess;
71 M mtx;
72
73 // Locker thread launches and exits without releasing the mutex
74 ipcdetail::OS_thread_t tm1;
75 ipcdetail::thread_launch(tm1, thread_adapter<M>(&lock_and_exit, 0, mtx));
76 ipcdetail::thread_join(thread: tm1);
77 BOOST_TRY {
78 test_owner_dead_mutex_do_lock(mtx, lock_type);
79 }
80 BOOST_CATCH(lock_exception& e) {
81 #ifndef BOOST_NO_EXCEPTIONS
82 if (e.get_error_code() == not_recoverable){
83 //Now try once again to lock it, to make sure it's not recoverable
84 BOOST_TRY {
85 test_owner_dead_mutex_do_lock(mtx, lock_type);
86 }
87 BOOST_CATCH(lock_exception& e) {
88 if (e.get_error_code() == not_recoverable)
89 return 0;
90 else{
91 std::cerr << "e.get_error_code() != not_recoverable! (2)";
92 return 3;
93 }
94 }
95 BOOST_CATCH(...) {
96 std::cerr << "lock_exception not thrown! (2)";
97 return 4;
98 } BOOST_CATCH_END
99 std::cerr << "Exception not thrown (2)!";
100 return 5;
101 }
102 else{
103 std::cerr << "e.get_error_code() != not_recoverable!";
104 return 1;
105 }
106 #endif //BOOST_NO_EXCEPTIONS
107 }
108 BOOST_CATCH(...) {
109 std::cerr << "lock_exception not thrown!";
110 return 2;
111 } BOOST_CATCH_END
112 std::cerr << "Exception not thrown!";
113 return 3;
114}
115
116template<class M>
117int test_owner_dead_mutex()
118{
119 int ret;
120 ret = test_owner_dead_mutex_impl<M>(OwnerDeadLock);
121 if (ret) return ret;
122 ret = test_owner_dead_mutex_impl<M>(OwnerDeadTryLock);
123 if (ret) return ret;
124 ret = test_owner_dead_mutex_impl<M>(OwnerDeadTimedLock);
125 return ret;
126}
127
128}}} //boost::interprocess::test
129
130
131int main ()
132{
133 using namespace boost::interprocess;
134 int ret;
135 std::cerr << "Testing interprocess_mutex";
136 ret = test::test_owner_dead_mutex<interprocess_mutex>();
137 if (ret)
138 return ret;
139
140 #ifdef BOOST_INTERPROCESS_POSIX_RECURSIVE_MUTEXES
141 std::cerr << "Testing interprocess_recursive_mutex";
142 ret = test::test_owner_dead_mutex<interprocess_recursive_mutex>();
143 if (ret)
144 return ret;
145 #endif
146
147 return ret;
148}
149
150#endif
151
152

source code of boost/libs/interprocess/test/mutex_owner_dead_test.cpp