1 | // Copyright (C) 2013 Vicente Botet |
---|---|
2 | // |
3 | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
4 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
5 | |
6 | //////////////////////////////////////////// |
7 | |
8 | //#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN |
9 | #include <iostream> |
10 | #include <boost/thread/thread_only.hpp> |
11 | #include <boost/thread/shared_mutex.hpp> |
12 | // shared_mutex_deadlock.cpp : Defines the entry point for the console application. |
13 | // |
14 | |
15 | |
16 | boost::shared_mutex mutex; |
17 | |
18 | void thread2_func() |
19 | { |
20 | int i (0); |
21 | for (;;) |
22 | { |
23 | if (mutex.timed_lock(relative_time: boost::posix_time::milliseconds(500))) |
24 | { |
25 | std::cout << "Unique lock acquired"<< std::endl |
26 | << "Test successful"<< std::endl; |
27 | mutex.unlock(); |
28 | break; |
29 | } |
30 | ++i; |
31 | if (i == 100) |
32 | { |
33 | std::cout << "Test failed. App is deadlocked"<< std::endl; |
34 | break; |
35 | } |
36 | boost::this_thread::sleep(rel_time: boost::posix_time::seconds(1)); |
37 | } |
38 | } |
39 | |
40 | void thread3_func() |
41 | { |
42 | boost::shared_lock<boost::shared_mutex> lock (mutex); |
43 | std::cout << "Shared lock acquired"<< std::endl |
44 | << "Test successful"<< std::endl; |
45 | } |
46 | |
47 | void thread3_func_workaround() |
48 | { |
49 | for (;;) |
50 | { |
51 | if (mutex.timed_lock_shared(relative_time: boost::posix_time::milliseconds(200))) |
52 | { |
53 | std::cout << "Shared lock acquired"<< std::endl |
54 | << "Test successful"<< std::endl; |
55 | mutex.unlock_shared(); |
56 | break; |
57 | } |
58 | boost::this_thread::sleep(rel_time: boost::posix_time::milliseconds(100)); |
59 | } |
60 | } |
61 | |
62 | int main() |
63 | { |
64 | std::cout << "Starting"<< std::endl; |
65 | |
66 | // 1 - lock the mutex |
67 | boost::shared_lock<boost::shared_mutex> lock (mutex); |
68 | |
69 | // 2 - start thread#2 |
70 | boost::thread thread2(&thread2_func); |
71 | |
72 | // 3 - sleep |
73 | boost::this_thread::sleep(rel_time: boost::posix_time::milliseconds(10)); |
74 | |
75 | std::cout << "Thread#2 is waiting"<< std::endl; |
76 | |
77 | // - start thread3 |
78 | boost::thread thread3(&thread3_func); |
79 | //boost::thread thread3(&thread3_func_workaround); |
80 | |
81 | std::cout << "Thread#3 is started and blocked. It never will waked"<< std::endl; |
82 | |
83 | thread3.join(); // will never return |
84 | |
85 | lock.unlock(); // release shared ownership. thread#2 will take unique ownership |
86 | |
87 | thread2.join(); |
88 | |
89 | std::cout << "Finished"<< std::endl; |
90 | return 0; |
91 | } |
92 | |
93 | |
94 | |
95 |