test_7571.cpp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. // Copyright (C) 2012 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. #define BOOST_THREAD_VERSION 2
  6. #include <boost/date_time.hpp>
  7. #include <boost/thread/mutex.hpp>
  8. #include <boost/thread/thread_only.hpp>
  9. #include <iostream>
  10. // Number should be big enough to allow context switch between threads, otherwise the bug doesn't show.
  11. static int MAX_COUNTS;
  12. class ItemKeeper {
  13. public:
  14. ItemKeeper() { }
  15. void doSomething() {
  16. boost::unique_lock<boost::mutex> scoped_lock(mutex);
  17. int counts = MAX_COUNTS;
  18. while (counts--);
  19. }
  20. private:
  21. boost::mutex mutex;
  22. };
  23. ItemKeeper itemKeeper;
  24. int MAX_ITERATIONS(5);
  25. void threadFunc(int invokerID, bool& exceptionOccurred) {
  26. try {
  27. for (int i = 0; i < MAX_ITERATIONS; i++) {
  28. std::cout << "Thread " << invokerID << ", iteration " << i << std::endl;
  29. itemKeeper.doSomething();
  30. }
  31. } catch (...) {
  32. exceptionOccurred = true;
  33. }
  34. }
  35. int main(int argc, char* argv[]) {
  36. if (argc < 2) {
  37. MAX_COUNTS = 5000000;
  38. } else {
  39. std::string valueStr(argv[1]);
  40. bool has_only_digits = (valueStr.find_first_not_of( "0123456789" ) == std::string::npos);
  41. if (has_only_digits) {
  42. std::istringstream aStream(valueStr);
  43. aStream >> MAX_COUNTS;
  44. } else {
  45. std::cerr << "Argument should be an integer\n";
  46. return 1;
  47. }
  48. }
  49. bool exceptionOccurred1(false);
  50. bool exceptionOccurred2(false);
  51. boost::thread thread1(threadFunc, 1, boost::ref(exceptionOccurred1));
  52. boost::thread thread2(threadFunc, 2, boost::ref(exceptionOccurred2));
  53. boost::posix_time::time_duration timeout = boost::posix_time::milliseconds(10000*100);
  54. bool deadlockOccured(false);
  55. //thread1.join();
  56. //thread2.join();
  57. if (!thread1.timed_join(timeout)) {
  58. deadlockOccured = true;
  59. thread1.interrupt();
  60. }
  61. if (!thread2.timed_join(timeout)) {
  62. deadlockOccured = true;
  63. thread2.interrupt();
  64. }
  65. if (deadlockOccured) {
  66. std::cout << "Deadlock occurred\n";
  67. return 1;
  68. }
  69. if (exceptionOccurred1 || exceptionOccurred2) {
  70. std::cout << "Exception occurred\n";
  71. return 1;
  72. }
  73. return 0;
  74. }