diff --git a/include/libtorrent/alert.hpp b/include/libtorrent/alert.hpp index b217572c9..a42a3fb2d 100644 --- a/include/libtorrent/alert.hpp +++ b/include/libtorrent/alert.hpp @@ -175,7 +175,7 @@ namespace libtorrent { std::deque m_alerts; mutable mutex m_mutex; - condition m_condition; + condition_variable m_condition; boost::uint32_t m_alert_mask; size_t m_queue_size_limit; boost::function)> m_dispatch; diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index bdd6c9cf6..ff4166205 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -521,7 +521,7 @@ namespace libtorrent // used when posting synchronous function // calls to session_impl and torrent objects mutable libtorrent::mutex mut; - mutable libtorrent::condition cond; + mutable libtorrent::condition_variable cond; void inc_disk_queue(int channel) { diff --git a/include/libtorrent/thread.hpp b/include/libtorrent/thread.hpp index 48d18c43b..5632e8679 100644 --- a/include/libtorrent/thread.hpp +++ b/include/libtorrent/thread.hpp @@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE. #define TORRENT_THREAD_HPP_INCLUDED #include "libtorrent/config.hpp" +#include "libtorrent/time.hpp" #if defined TORRENT_WINDOWS || defined TORRENT_CYGWIN // asio assumes that the windows error codes are defined already @@ -58,15 +59,13 @@ namespace libtorrent TORRENT_EXPORT void sleep(int milliseconds); - // TODO: 3 make this interface compatible with c++11 - // to allow for smooth transition for platforms with support - struct TORRENT_EXTRA_EXPORT condition + struct TORRENT_EXTRA_EXPORT condition_variable { - condition(); - ~condition(); + condition_variable(); + ~condition_variable(); void wait(mutex::scoped_lock& l); - void timed_wait(mutex::scoped_lock& l, int sleep_ms); - void signal_all(mutex::scoped_lock& l); + void wait_for(mutex::scoped_lock& l, time_duration rel_time); + void notify_all(); private: #ifdef BOOST_HAS_PTHREADS pthread_cond_t m_cond; diff --git a/src/alert.cpp b/src/alert.cpp index 757586e03..bbddf7194 100644 --- a/src/alert.cpp +++ b/src/alert.cpp @@ -359,7 +359,7 @@ namespace libtorrent { if (!m_alerts.empty()) return m_alerts.front(); // this call can be interrupted prematurely by other signals - m_condition.timed_wait(lock, total_milliseconds(max_wait)); + m_condition.wait_for(lock, max_wait); if (!m_alerts.empty()) return m_alerts.front(); return NULL; @@ -440,7 +440,7 @@ namespace libtorrent { { m_alerts.push_back(alert_.release()); if (m_alerts.size() == 1) - m_condition.signal_all(l); + m_condition.notify_all(); } } diff --git a/src/rss.cpp b/src/rss.cpp index b5b525c31..3a5429a8f 100644 --- a/src/rss.cpp +++ b/src/rss.cpp @@ -615,7 +615,7 @@ int feed::next_update(time_t now) const } // defined in session.cpp -void fun_wrap(bool* done, condition* e, mutex* m, boost::function f); +void fun_wrap(bool* done, condition_variable* e, mutex* m, boost::function f); #define TORRENT_ASYNC_CALL(x) \ boost::shared_ptr f = m_feed_ptr.lock(); \ diff --git a/src/session.cpp b/src/session.cpp index 0fa3b4de9..387ed8587 100644 --- a/src/session.cpp +++ b/src/session.cpp @@ -304,20 +304,20 @@ namespace libtorrent // wrapper around a function that's executed in the network thread // ans synchronized in the client thread template - void fun_ret(R* ret, bool* done, condition* e, mutex* m, boost::function f) + void fun_ret(R* ret, bool* done, condition_variable* e, mutex* m, boost::function f) { *ret = f(); mutex::scoped_lock l(*m); *done = true; - e->signal_all(l); + e->notify_all(); } - void fun_wrap(bool* done, condition* e, mutex* m, boost::function f) + void fun_wrap(bool* done, condition_variable* e, mutex* m, boost::function f) { f(); mutex::scoped_lock l(*m); *done = true; - e->signal_all(l); + e->notify_all(); } #define TORRENT_ASYNC_CALL(x) \ diff --git a/src/thread.cpp b/src/thread.cpp index 63b7e64f0..2f3c9b1b7 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -57,56 +57,55 @@ namespace libtorrent #ifdef BOOST_HAS_PTHREADS - condition::condition() + condition_variable::condition_variable() { pthread_cond_init(&m_cond, 0); } - condition::~condition() + condition_variable::~condition_variable() { pthread_cond_destroy(&m_cond); } - void condition::wait(mutex::scoped_lock& l) + void condition_variable::wait(mutex::scoped_lock& l) { TORRENT_ASSERT(l.locked()); // wow, this is quite a hack pthread_cond_wait(&m_cond, (::pthread_mutex_t*)&l.mutex()); } - void condition::timed_wait(mutex::scoped_lock& l, int sleep_ms) + void condition_variable::wait_for(mutex::scoped_lock& l, time_duration rel_time) { TORRENT_ASSERT(l.locked()); struct timeval tv; struct timespec ts; gettimeofday(&tv, NULL); - boost::uint64_t microseconds = tv.tv_usec + boost::uint64_t(sleep_ms % 1000) * 1000; + boost::uint64_t microseconds = tv.tv_usec + total_microseconds(rel_time) % 1000000; ts.tv_nsec = (microseconds % 1000000) * 1000; - ts.tv_sec = tv.tv_sec + sleep_ms / 1000 + microseconds / 1000000; + ts.tv_sec = tv.tv_sec + total_seconds(rel_time) + microseconds / 1000000; // wow, this is quite a hack pthread_cond_timedwait(&m_cond, (::pthread_mutex_t*)&l.mutex(), &ts); } - void condition::signal_all(mutex::scoped_lock& l) + void condition_variable::notify_all() { - TORRENT_ASSERT(l.locked()); pthread_cond_broadcast(&m_cond); } #elif defined TORRENT_WINDOWS || defined TORRENT_CYGWIN - condition::condition() + condition_variable::condition_variable() : m_num_waiters(0) { m_sem = CreateSemaphore(0, 0, INT_MAX, 0); } - condition::~condition() + condition_variable::~condition_variable() { CloseHandle(m_sem); } - void condition::wait(mutex::scoped_lock& l) + void condition_variable::wait(mutex::scoped_lock& l) { TORRENT_ASSERT(l.locked()); ++m_num_waiters; @@ -116,34 +115,33 @@ namespace libtorrent --m_num_waiters; } - void condition::timed_wait(mutex::scoped_lock& l, int sleep_ms) + void condition_variable::wait_for(mutex::scoped_lock& l, time_duration rel_time) { TORRENT_ASSERT(l.locked()); ++m_num_waiters; l.unlock(); - WaitForSingleObject(m_sem, sleep_ms); + WaitForSingleObject(m_sem, total_milliseconds(rel_time)); l.lock(); --m_num_waiters; } - void condition::signal_all(mutex::scoped_lock& l) + void condition_variable::notify_all() { - TORRENT_ASSERT(l.locked()); ReleaseSemaphore(m_sem, m_num_waiters, 0); } #elif defined TORRENT_BEOS - condition::condition() + condition_variable::condition_variable() : m_num_waiters(0) { m_sem = create_sem(0, 0); } - condition::~condition() + condition_variable::~condition_variable() { delete_sem(m_sem); } - void condition::wait(mutex::scoped_lock& l) + void condition_variable::wait(mutex::scoped_lock& l) { TORRENT_ASSERT(l.locked()); ++m_num_waiters; @@ -153,19 +151,18 @@ namespace libtorrent --m_num_waiters; } - void condition::timed_wait(mutex::scoped_lock& l, int sleep_ms) + void condition_variable::wait_for(mutex::scoped_lock& l, time_duration rel_time) { TORRENT_ASSERT(l.locked()); ++m_num_waiters; l.unlock(); - acquire_sem_etc(m_sem, 1, B_RELATIVE_TIMEOUT, bigtime_t(sleep_ms) * 1000); + acquire_sem_etc(m_sem, 1, B_RELATIVE_TIMEOUT, total_microseconds(rel_time)); l.lock(); --m_num_waiters; } - void condition::signal_all(mutex::scoped_lock& l) + void condition_variable::notify_all() { - TORRENT_ASSERT(l.locked()); release_sem_etc(m_sem, m_num_waiters, 0); } #else diff --git a/src/torrent_handle.cpp b/src/torrent_handle.cpp index 40400fe76..904e86368 100644 --- a/src/torrent_handle.cpp +++ b/src/torrent_handle.cpp @@ -147,16 +147,16 @@ namespace libtorrent torrent_status::~torrent_status() {} template - void fun_ret(R* ret, bool* done, condition* e, mutex* m, boost::function f) + void fun_ret(R* ret, bool* done, condition_variable* e, mutex* m, boost::function f) { *ret = f(); mutex::scoped_lock l(*m); *done = true; - e->signal_all(l); + e->notify_all(); } // defined in session.cpp - void fun_wrap(bool* done, condition* e, mutex* m, boost::function f); + void fun_wrap(bool* done, condition_variable* e, mutex* m, boost::function f); #define TORRENT_ASYNC_CALL(x) \ boost::shared_ptr t = m_torrent.lock(); \ diff --git a/test/test_threads.cpp b/test/test_threads.cpp index 4f85f0a9d..ec569e9c4 100644 --- a/test/test_threads.cpp +++ b/test/test_threads.cpp @@ -37,7 +37,7 @@ POSSIBILITY OF SUCH DAMAGE. using namespace libtorrent; -void fun(condition* s, libtorrent::mutex* m, int i) +void fun(condition_variable* s, libtorrent::mutex* m, int i) { fprintf(stderr, "thread %d waiting\n", i); libtorrent::mutex::scoped_lock l(*m); @@ -47,7 +47,7 @@ void fun(condition* s, libtorrent::mutex* m, int i) int test_main() { - condition cond; + condition_variable cond; libtorrent::mutex m; std::list threads; for (int i = 0; i < 20; ++i) @@ -55,11 +55,11 @@ int test_main() threads.push_back(new thread(boost::bind(&fun, &cond, &m, i))); } - // make sure all threads are waiting on the condition + // make sure all threads are waiting on the condition_variable sleep(10); libtorrent::mutex::scoped_lock l(m); - cond.signal_all(l); + cond.notify_all(); l.unlock(); for (std::list::iterator i = threads.begin(); i != threads.end(); ++i)