mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-12 05:02:31 +00:00
* Fixed a race condition where the releasing of the global lock before calling polling would cause problems. Now a thread that acquires the global lock and wants to remove or change fd's from the main thread.
git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@1182 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
@@ -579,10 +579,12 @@ DownloadList::confirm_finished(Download* download) {
|
||||
rpc::call_command("d.connection_current.set", rpc::call_command_void("d.connection_seed", rpc::make_target(download)), rpc::make_target(download));
|
||||
download->set_priority(download->priority());
|
||||
|
||||
if (rpc::call_command_value("d.peers_min", rpc::make_target(download)) == rpc::call_command_value("throttle.min_peers.normal") && rpc::call_command_value("throttle.min_peers.seed") >= 0)
|
||||
if (rpc::call_command_value("d.peers_min", rpc::make_target(download)) == rpc::call_command_value("throttle.min_peers.normal") &&
|
||||
rpc::call_command_value("throttle.min_peers.seed") >= 0)
|
||||
rpc::call_command("d.peers_min.set", rpc::call_command_void("throttle.min_peers.seed"), rpc::make_target(download));
|
||||
|
||||
if (rpc::call_command_value("d.peers_max", rpc::make_target(download)) == rpc::call_command_value("throttle.max_peers.normal") && rpc::call_command_value("throttle.max_peers.seed") >= 0)
|
||||
if (rpc::call_command_value("d.peers_max", rpc::make_target(download)) == rpc::call_command_value("throttle.max_peers.normal") &&
|
||||
rpc::call_command_value("throttle.max_peers.seed") >= 0)
|
||||
rpc::call_command("d.peers_max.set", rpc::call_command_void("throttle.max_peers.seed"), rpc::make_target(download));
|
||||
|
||||
// Do this before the slots are called in case one of them closes
|
||||
|
||||
@@ -69,7 +69,11 @@ PollManagerEPoll::poll(rak::timer timeout) {
|
||||
timeout = std::min(timeout, rak::timer(torrent::next_timeout())) + 1000;
|
||||
|
||||
ThreadBase::release_global_lock();
|
||||
ThreadBase::entering_main_polling();
|
||||
|
||||
int status = static_cast<torrent::PollEPoll*>(m_poll)->poll((timeout.usec() + 999) / 1000);
|
||||
|
||||
ThreadBase::leaving_main_polling();
|
||||
ThreadBase::acquire_global_lock();
|
||||
|
||||
if (status == -1)
|
||||
|
||||
@@ -70,7 +70,11 @@ PollManagerKQueue::poll(rak::timer timeout) {
|
||||
timeout = std::min(timeout, rak::timer(torrent::next_timeout())) + 1000;
|
||||
|
||||
ThreadBase::release_global_lock();
|
||||
ThreadBase::entering_main_polling();
|
||||
|
||||
int status = static_cast<torrent::PollKQueue*>(m_poll)->poll((timeout.usec() + 999) / 1000);
|
||||
|
||||
ThreadBase::leaving_main_polling();
|
||||
ThreadBase::acquire_global_lock();
|
||||
|
||||
if (status == -1)
|
||||
|
||||
@@ -92,8 +92,12 @@ PollManagerSelect::poll(rak::timer timeout) {
|
||||
|
||||
timeval t = timeout.tval();
|
||||
|
||||
ThreadBase::entering_main_polling();
|
||||
ThreadBase::release_global_lock();
|
||||
|
||||
int status = select(maxFd + 1, m_readSet, m_writeSet, m_errorSet, &t);
|
||||
|
||||
ThreadBase::leaving_main_polling();
|
||||
ThreadBase::acquire_global_lock();
|
||||
|
||||
if (status == -1)
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ class Control;
|
||||
extern rak::priority_queue_default taskScheduler;
|
||||
extern rak::timer cachedTime;
|
||||
|
||||
extern Control* control;
|
||||
extern Control* control;
|
||||
// extern __thread ThreadBase* main_thread; // Only use for worker threads for now.
|
||||
extern ThreadMain* main_thread;
|
||||
extern ThreadWorker* worker_thread;
|
||||
|
||||
+3
-1
@@ -165,8 +165,10 @@ SCgi::receive_call(SCgiTask* task, const char* buffer, uint32_t length) {
|
||||
slotWrite.set(rak::mem_fn(task, &SCgiTask::receive_write));
|
||||
|
||||
ThreadBase::acquire_global_lock();
|
||||
// bool result = m_slotProcess(buffer, length, slotWrite);
|
||||
ThreadBase::interrupt_main_polling();
|
||||
|
||||
bool result = xmlrpc.process(buffer, length, slotWrite);
|
||||
|
||||
ThreadBase::release_global_lock();
|
||||
|
||||
return result;
|
||||
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
private:
|
||||
static void caught(int signum);
|
||||
|
||||
static Slot m_handlers[HIGHEST_SIGNAL];
|
||||
static Slot m_handlers[HIGHEST_SIGNAL];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -196,3 +196,13 @@ ThreadBase::queue_item(thread_base_func newFunc) {
|
||||
if (m_state == STATE_ACTIVE)
|
||||
pthread_kill(m_thread, SIGUSR1);
|
||||
}
|
||||
|
||||
void
|
||||
ThreadBase::interrupt_main_polling() {
|
||||
do {
|
||||
if (!ThreadBase::is_main_polling())
|
||||
return;
|
||||
|
||||
pthread_kill(main_thread->m_thread, SIGUSR1);
|
||||
} while (1);
|
||||
}
|
||||
|
||||
@@ -84,6 +84,9 @@ public:
|
||||
|
||||
static void* event_loop(ThreadBase* threadBase);
|
||||
|
||||
// Move to libtorrent some day.
|
||||
static void interrupt_main_polling();
|
||||
|
||||
protected:
|
||||
inline rak::timer client_next_timeout();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user