diff --git a/test/test_threads.cpp b/test/test_threads.cpp index ec569e9c4..74ed3ed96 100644 --- a/test/test_threads.cpp +++ b/test/test_threads.cpp @@ -33,32 +33,88 @@ POSSIBILITY OF SUCH DAMAGE. #include #include #include "libtorrent/thread.hpp" +#include #include "test.hpp" +using boost::detail::atomic_count; using namespace libtorrent; -void fun(condition_variable* s, libtorrent::mutex* m, int i) +void fun(condition_variable* s, libtorrent::mutex* m, int* waiting, int i) { fprintf(stderr, "thread %d waiting\n", i); libtorrent::mutex::scoped_lock l(*m); + *waiting += 1; s->wait(l); fprintf(stderr, "thread %d done\n", i); } +void increment(condition_variable* s, libtorrent::mutex* m, int* waiting, atomic_count* c) +{ + libtorrent::mutex::scoped_lock l(*m); + *waiting += 1; + s->wait(l); + l.unlock(); + for (int i = 0; i < 1000000; ++i) + ++*c; +} + +void decrement(condition_variable* s, libtorrent::mutex* m, int* waiting, atomic_count* c) +{ + libtorrent::mutex::scoped_lock l(*m); + *waiting += 1; + s->wait(l); + l.unlock(); + for (int i = 0; i < 1000000; ++i) + --*c; +} + int test_main() { condition_variable cond; libtorrent::mutex m; std::list threads; + int waiting = 0; for (int i = 0; i < 20; ++i) { - threads.push_back(new thread(boost::bind(&fun, &cond, &m, i))); + threads.push_back(new thread(boost::bind(&fun, &cond, &m, &waiting, i))); } // make sure all threads are waiting on the condition_variable - sleep(10); - libtorrent::mutex::scoped_lock l(m); + while (waiting < 20) + { + l.unlock(); + sleep(10); + l.lock(); + } + + cond.notify_all(); + l.unlock(); + + for (std::list::iterator i = threads.begin(); i != threads.end(); ++i) + { + (*i)->join(); + delete *i; + } + threads.clear(); + + waiting = 0; + atomic_count c(0); + for (int i = 0; i < 3; ++i) + { + threads.push_back(new thread(boost::bind(&increment, &cond, &m, &waiting, &c))); + threads.push_back(new thread(boost::bind(&decrement, &cond, &m, &waiting, &c))); + } + + // make sure all threads are waiting on the condition_variable + l.lock(); + while (waiting < 6) + { + l.unlock(); + sleep(10); + l.lock(); + } + cond.notify_all(); l.unlock(); @@ -68,6 +124,8 @@ int test_main() delete *i; } + TEST_CHECK(c == 0); + return 0; }