6dad044ab7
[SVN r83548]
94 lines
2.2 KiB
C++
94 lines
2.2 KiB
C++
// 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;
|
|
}
|
|
|