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 thread2_func()18void thread2_func() 19 { 20 int i (0); 21 for (;;) 22 { 23 if (mutex.timed_lock(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(boost::posix_time::seconds(1)); 37 } 38 } 39 thread3_func()40void 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 thread3_func_workaround()47void thread3_func_workaround() 48 { 49 for (;;) 50 { 51 if (mutex.timed_lock_shared(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(boost::posix_time::milliseconds(100)); 59 } 60 } 61 main()62int 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(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