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

source code of boost/libs/thread/test/test_7571.cpp