forked from premiere/premiere-libtorrent
make condition variable c++11 compatible
This commit is contained in:
parent
1b0ddc5560
commit
d6fecf4c34
|
@ -175,7 +175,7 @@ namespace libtorrent {
|
||||||
|
|
||||||
std::deque<alert*> m_alerts;
|
std::deque<alert*> m_alerts;
|
||||||
mutable mutex m_mutex;
|
mutable mutex m_mutex;
|
||||||
condition m_condition;
|
condition_variable m_condition;
|
||||||
boost::uint32_t m_alert_mask;
|
boost::uint32_t m_alert_mask;
|
||||||
size_t m_queue_size_limit;
|
size_t m_queue_size_limit;
|
||||||
boost::function<void(std::auto_ptr<alert>)> m_dispatch;
|
boost::function<void(std::auto_ptr<alert>)> m_dispatch;
|
||||||
|
|
|
@ -521,7 +521,7 @@ namespace libtorrent
|
||||||
// used when posting synchronous function
|
// used when posting synchronous function
|
||||||
// calls to session_impl and torrent objects
|
// calls to session_impl and torrent objects
|
||||||
mutable libtorrent::mutex mut;
|
mutable libtorrent::mutex mut;
|
||||||
mutable libtorrent::condition cond;
|
mutable libtorrent::condition_variable cond;
|
||||||
|
|
||||||
void inc_disk_queue(int channel)
|
void inc_disk_queue(int channel)
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define TORRENT_THREAD_HPP_INCLUDED
|
#define TORRENT_THREAD_HPP_INCLUDED
|
||||||
|
|
||||||
#include "libtorrent/config.hpp"
|
#include "libtorrent/config.hpp"
|
||||||
|
#include "libtorrent/time.hpp"
|
||||||
|
|
||||||
#if defined TORRENT_WINDOWS || defined TORRENT_CYGWIN
|
#if defined TORRENT_WINDOWS || defined TORRENT_CYGWIN
|
||||||
// asio assumes that the windows error codes are defined already
|
// asio assumes that the windows error codes are defined already
|
||||||
|
@ -58,15 +59,13 @@ namespace libtorrent
|
||||||
|
|
||||||
TORRENT_EXPORT void sleep(int milliseconds);
|
TORRENT_EXPORT void sleep(int milliseconds);
|
||||||
|
|
||||||
// TODO: 3 make this interface compatible with c++11
|
struct TORRENT_EXTRA_EXPORT condition_variable
|
||||||
// to allow for smooth transition for platforms with support
|
|
||||||
struct TORRENT_EXTRA_EXPORT condition
|
|
||||||
{
|
{
|
||||||
condition();
|
condition_variable();
|
||||||
~condition();
|
~condition_variable();
|
||||||
void wait(mutex::scoped_lock& l);
|
void wait(mutex::scoped_lock& l);
|
||||||
void timed_wait(mutex::scoped_lock& l, int sleep_ms);
|
void wait_for(mutex::scoped_lock& l, time_duration rel_time);
|
||||||
void signal_all(mutex::scoped_lock& l);
|
void notify_all();
|
||||||
private:
|
private:
|
||||||
#ifdef BOOST_HAS_PTHREADS
|
#ifdef BOOST_HAS_PTHREADS
|
||||||
pthread_cond_t m_cond;
|
pthread_cond_t m_cond;
|
||||||
|
|
|
@ -359,7 +359,7 @@ namespace libtorrent {
|
||||||
if (!m_alerts.empty()) return m_alerts.front();
|
if (!m_alerts.empty()) return m_alerts.front();
|
||||||
|
|
||||||
// this call can be interrupted prematurely by other signals
|
// 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();
|
if (!m_alerts.empty()) return m_alerts.front();
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -440,7 +440,7 @@ namespace libtorrent {
|
||||||
{
|
{
|
||||||
m_alerts.push_back(alert_.release());
|
m_alerts.push_back(alert_.release());
|
||||||
if (m_alerts.size() == 1)
|
if (m_alerts.size() == 1)
|
||||||
m_condition.signal_all(l);
|
m_condition.notify_all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -615,7 +615,7 @@ int feed::next_update(time_t now) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// defined in session.cpp
|
// defined in session.cpp
|
||||||
void fun_wrap(bool* done, condition* e, mutex* m, boost::function<void(void)> f);
|
void fun_wrap(bool* done, condition_variable* e, mutex* m, boost::function<void(void)> f);
|
||||||
|
|
||||||
#define TORRENT_ASYNC_CALL(x) \
|
#define TORRENT_ASYNC_CALL(x) \
|
||||||
boost::shared_ptr<feed> f = m_feed_ptr.lock(); \
|
boost::shared_ptr<feed> f = m_feed_ptr.lock(); \
|
||||||
|
|
|
@ -304,20 +304,20 @@ namespace libtorrent
|
||||||
// wrapper around a function that's executed in the network thread
|
// wrapper around a function that's executed in the network thread
|
||||||
// ans synchronized in the client thread
|
// ans synchronized in the client thread
|
||||||
template <class R>
|
template <class R>
|
||||||
void fun_ret(R* ret, bool* done, condition* e, mutex* m, boost::function<R(void)> f)
|
void fun_ret(R* ret, bool* done, condition_variable* e, mutex* m, boost::function<R(void)> f)
|
||||||
{
|
{
|
||||||
*ret = f();
|
*ret = f();
|
||||||
mutex::scoped_lock l(*m);
|
mutex::scoped_lock l(*m);
|
||||||
*done = true;
|
*done = true;
|
||||||
e->signal_all(l);
|
e->notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
void fun_wrap(bool* done, condition* e, mutex* m, boost::function<void(void)> f)
|
void fun_wrap(bool* done, condition_variable* e, mutex* m, boost::function<void(void)> f)
|
||||||
{
|
{
|
||||||
f();
|
f();
|
||||||
mutex::scoped_lock l(*m);
|
mutex::scoped_lock l(*m);
|
||||||
*done = true;
|
*done = true;
|
||||||
e->signal_all(l);
|
e->notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TORRENT_ASYNC_CALL(x) \
|
#define TORRENT_ASYNC_CALL(x) \
|
||||||
|
|
|
@ -57,56 +57,55 @@ namespace libtorrent
|
||||||
|
|
||||||
#ifdef BOOST_HAS_PTHREADS
|
#ifdef BOOST_HAS_PTHREADS
|
||||||
|
|
||||||
condition::condition()
|
condition_variable::condition_variable()
|
||||||
{
|
{
|
||||||
pthread_cond_init(&m_cond, 0);
|
pthread_cond_init(&m_cond, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
condition::~condition()
|
condition_variable::~condition_variable()
|
||||||
{
|
{
|
||||||
pthread_cond_destroy(&m_cond);
|
pthread_cond_destroy(&m_cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
void condition::wait(mutex::scoped_lock& l)
|
void condition_variable::wait(mutex::scoped_lock& l)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(l.locked());
|
TORRENT_ASSERT(l.locked());
|
||||||
// wow, this is quite a hack
|
// wow, this is quite a hack
|
||||||
pthread_cond_wait(&m_cond, (::pthread_mutex_t*)&l.mutex());
|
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());
|
TORRENT_ASSERT(l.locked());
|
||||||
|
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
gettimeofday(&tv, NULL);
|
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_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
|
// wow, this is quite a hack
|
||||||
pthread_cond_timedwait(&m_cond, (::pthread_mutex_t*)&l.mutex(), &ts);
|
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);
|
pthread_cond_broadcast(&m_cond);
|
||||||
}
|
}
|
||||||
#elif defined TORRENT_WINDOWS || defined TORRENT_CYGWIN
|
#elif defined TORRENT_WINDOWS || defined TORRENT_CYGWIN
|
||||||
condition::condition()
|
condition_variable::condition_variable()
|
||||||
: m_num_waiters(0)
|
: m_num_waiters(0)
|
||||||
{
|
{
|
||||||
m_sem = CreateSemaphore(0, 0, INT_MAX, 0);
|
m_sem = CreateSemaphore(0, 0, INT_MAX, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
condition::~condition()
|
condition_variable::~condition_variable()
|
||||||
{
|
{
|
||||||
CloseHandle(m_sem);
|
CloseHandle(m_sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
void condition::wait(mutex::scoped_lock& l)
|
void condition_variable::wait(mutex::scoped_lock& l)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(l.locked());
|
TORRENT_ASSERT(l.locked());
|
||||||
++m_num_waiters;
|
++m_num_waiters;
|
||||||
|
@ -116,34 +115,33 @@ namespace libtorrent
|
||||||
--m_num_waiters;
|
--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());
|
TORRENT_ASSERT(l.locked());
|
||||||
++m_num_waiters;
|
++m_num_waiters;
|
||||||
l.unlock();
|
l.unlock();
|
||||||
WaitForSingleObject(m_sem, sleep_ms);
|
WaitForSingleObject(m_sem, total_milliseconds(rel_time));
|
||||||
l.lock();
|
l.lock();
|
||||||
--m_num_waiters;
|
--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);
|
ReleaseSemaphore(m_sem, m_num_waiters, 0);
|
||||||
}
|
}
|
||||||
#elif defined TORRENT_BEOS
|
#elif defined TORRENT_BEOS
|
||||||
condition::condition()
|
condition_variable::condition_variable()
|
||||||
: m_num_waiters(0)
|
: m_num_waiters(0)
|
||||||
{
|
{
|
||||||
m_sem = create_sem(0, 0);
|
m_sem = create_sem(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
condition::~condition()
|
condition_variable::~condition_variable()
|
||||||
{
|
{
|
||||||
delete_sem(m_sem);
|
delete_sem(m_sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
void condition::wait(mutex::scoped_lock& l)
|
void condition_variable::wait(mutex::scoped_lock& l)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(l.locked());
|
TORRENT_ASSERT(l.locked());
|
||||||
++m_num_waiters;
|
++m_num_waiters;
|
||||||
|
@ -153,19 +151,18 @@ namespace libtorrent
|
||||||
--m_num_waiters;
|
--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());
|
TORRENT_ASSERT(l.locked());
|
||||||
++m_num_waiters;
|
++m_num_waiters;
|
||||||
l.unlock();
|
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();
|
l.lock();
|
||||||
--m_num_waiters;
|
--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);
|
release_sem_etc(m_sem, m_num_waiters, 0);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -147,16 +147,16 @@ namespace libtorrent
|
||||||
torrent_status::~torrent_status() {}
|
torrent_status::~torrent_status() {}
|
||||||
|
|
||||||
template <class R>
|
template <class R>
|
||||||
void fun_ret(R* ret, bool* done, condition* e, mutex* m, boost::function<R(void)> f)
|
void fun_ret(R* ret, bool* done, condition_variable* e, mutex* m, boost::function<R(void)> f)
|
||||||
{
|
{
|
||||||
*ret = f();
|
*ret = f();
|
||||||
mutex::scoped_lock l(*m);
|
mutex::scoped_lock l(*m);
|
||||||
*done = true;
|
*done = true;
|
||||||
e->signal_all(l);
|
e->notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
// defined in session.cpp
|
// defined in session.cpp
|
||||||
void fun_wrap(bool* done, condition* e, mutex* m, boost::function<void(void)> f);
|
void fun_wrap(bool* done, condition_variable* e, mutex* m, boost::function<void(void)> f);
|
||||||
|
|
||||||
#define TORRENT_ASYNC_CALL(x) \
|
#define TORRENT_ASYNC_CALL(x) \
|
||||||
boost::shared_ptr<torrent> t = m_torrent.lock(); \
|
boost::shared_ptr<torrent> t = m_torrent.lock(); \
|
||||||
|
|
|
@ -37,7 +37,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace libtorrent;
|
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);
|
fprintf(stderr, "thread %d waiting\n", i);
|
||||||
libtorrent::mutex::scoped_lock l(*m);
|
libtorrent::mutex::scoped_lock l(*m);
|
||||||
|
@ -47,7 +47,7 @@ void fun(condition* s, libtorrent::mutex* m, int i)
|
||||||
|
|
||||||
int test_main()
|
int test_main()
|
||||||
{
|
{
|
||||||
condition cond;
|
condition_variable cond;
|
||||||
libtorrent::mutex m;
|
libtorrent::mutex m;
|
||||||
std::list<thread*> threads;
|
std::list<thread*> threads;
|
||||||
for (int i = 0; i < 20; ++i)
|
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)));
|
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);
|
sleep(10);
|
||||||
|
|
||||||
libtorrent::mutex::scoped_lock l(m);
|
libtorrent::mutex::scoped_lock l(m);
|
||||||
cond.signal_all(l);
|
cond.notify_all();
|
||||||
l.unlock();
|
l.unlock();
|
||||||
|
|
||||||
for (std::list<thread*>::iterator i = threads.begin(); i != threads.end(); ++i)
|
for (std::list<thread*>::iterator i = threads.begin(); i != threads.end(); ++i)
|
||||||
|
|
Loading…
Reference in New Issue