blob: a336795f4a65882ff42786aa104dde1ffe858cf3 [file] [log] [blame]
// Copyright (C) 2012 Vicente Botet
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_THREAD_VERSION 2
#include <boost/date_time.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread_only.hpp>
#include <iostream>
// Number should be big enough to allow context switch between threads, otherwise the bug doesn't show.
static int MAX_COUNTS;
class ItemKeeper {
public:
ItemKeeper() { }
void doSomething() {
boost::unique_lock<boost::mutex> scoped_lock(mutex);
int counts = MAX_COUNTS;
while (counts--);
}
private:
boost::mutex mutex;
};
ItemKeeper itemKeeper;
int MAX_ITERATIONS(5);
void threadFunc(int invokerID, bool& exceptionOccurred) {
try {
for (int i = 0; i < MAX_ITERATIONS; i++) {
std::cout << "Thread " << invokerID << ", iteration " << i << std::endl;
itemKeeper.doSomething();
}
} catch (...) {
exceptionOccurred = true;
}
}
int main(int argc, char* argv[]) {
if (argc < 2) {
MAX_COUNTS = 5000000;
} else {
std::string valueStr(argv[1]);
bool has_only_digits = (valueStr.find_first_not_of( "0123456789" ) == std::string::npos);
if (has_only_digits) {
std::istringstream aStream(valueStr);
aStream >> MAX_COUNTS;
} else {
std::cerr << "Argument should be an integer\n";
return 1;
}
}
bool exceptionOccurred1(false);
bool exceptionOccurred2(false);
boost::thread thread1(threadFunc, 1, boost::ref(exceptionOccurred1));
boost::thread thread2(threadFunc, 2, boost::ref(exceptionOccurred2));
boost::posix_time::time_duration timeout = boost::posix_time::milliseconds(10000*100);
bool deadlockOccured(false);
//thread1.join();
//thread2.join();
if (!thread1.timed_join(timeout)) {
deadlockOccured = true;
thread1.interrupt();
}
if (!thread2.timed_join(timeout)) {
deadlockOccured = true;
thread2.interrupt();
}
if (deadlockOccured) {
std::cout << "Deadlock occurred\n";
return 1;
}
if (exceptionOccurred1 || exceptionOccurred2) {
std::cout << "Exception occurred\n";
return 1;
}
return 0;
}