Ticket #7571: Main.cpp

File Main.cpp, 1.9 KB (added by yalon-l@…, 10 years ago)

Bug demonstrator

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