test_7755.cpp 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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. //#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
  7. #include <iostream>
  8. #include <boost/thread/thread_only.hpp>
  9. #include <boost/thread/shared_mutex.hpp>
  10. // shared_mutex_deadlock.cpp : Defines the entry point for the console application.
  11. //
  12. boost::shared_mutex mutex;
  13. void thread2_func()
  14. {
  15. int i (0);
  16. for (;;)
  17. {
  18. if (mutex.timed_lock(boost::posix_time::milliseconds(500)))
  19. {
  20. std::cout << "Unique lock acquired" << std::endl
  21. << "Test successful" << std::endl;
  22. mutex.unlock();
  23. break;
  24. }
  25. ++i;
  26. if (i == 100)
  27. {
  28. std::cout << "Test failed. App is deadlocked" << std::endl;
  29. break;
  30. }
  31. boost::this_thread::sleep(boost::posix_time::seconds(1));
  32. }
  33. }
  34. void thread3_func()
  35. {
  36. boost::shared_lock<boost::shared_mutex> lock (mutex);
  37. std::cout << "Shared lock acquired" << std::endl
  38. << "Test successful" << std::endl;
  39. }
  40. void thread3_func_workaround()
  41. {
  42. for (;;)
  43. {
  44. if (mutex.timed_lock_shared(boost::posix_time::milliseconds(200)))
  45. {
  46. std::cout << "Shared lock acquired" << std::endl
  47. << "Test successful" << std::endl;
  48. mutex.unlock_shared();
  49. break;
  50. }
  51. boost::this_thread::sleep(boost::posix_time::milliseconds(100));
  52. }
  53. }
  54. int main()
  55. {
  56. std::cout << "Starting" << std::endl;
  57. // 1 - lock the mutex
  58. boost::shared_lock<boost::shared_mutex> lock (mutex);
  59. // 2 - start thread#2
  60. boost::thread thread2(&thread2_func);
  61. // 3 - sleep
  62. boost::this_thread::sleep(boost::posix_time::milliseconds(10));
  63. std::cout << "Thread#2 is waiting" << std::endl;
  64. // - start thread3
  65. boost::thread thread3(&thread3_func);
  66. //boost::thread thread3(&thread3_func_workaround);
  67. std::cout << "Thread#3 is started and blocked. It never will waked" << std::endl;
  68. thread3.join(); // will never return
  69. lock.unlock(); // release shared ownership. thread#2 will take unique ownership
  70. thread2.join();
  71. std::cout << "Finished" << std::endl;
  72. return 0;
  73. }