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;
|
||||
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<void(std::auto_ptr<alert>)> m_dispatch;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<void(void)> f);
|
||||
void fun_wrap(bool* done, condition_variable* e, mutex* m, boost::function<void(void)> f);
|
||||
|
||||
#define TORRENT_ASYNC_CALL(x) \
|
||||
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
|
||||
// ans synchronized in the client thread
|
||||
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();
|
||||
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<void(void)> f)
|
||||
void fun_wrap(bool* done, condition_variable* e, mutex* m, boost::function<void(void)> f)
|
||||
{
|
||||
f();
|
||||
mutex::scoped_lock l(*m);
|
||||
*done = true;
|
||||
e->signal_all(l);
|
||||
e->notify_all();
|
||||
}
|
||||
|
||||
#define TORRENT_ASYNC_CALL(x) \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -147,16 +147,16 @@ namespace libtorrent
|
|||
torrent_status::~torrent_status() {}
|
||||
|
||||
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();
|
||||
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<void(void)> f);
|
||||
void fun_wrap(bool* done, condition_variable* e, mutex* m, boost::function<void(void)> f);
|
||||
|
||||
#define TORRENT_ASYNC_CALL(x) \
|
||||
boost::shared_ptr<torrent> t = m_torrent.lock(); \
|
||||
|
|
|
@ -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<thread*> 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<thread*>::iterator i = threads.begin(); i != threads.end(); ++i)
|
||||
|
|
Loading…
Reference in New Issue