* 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:
rakshasa
2010-10-22 11:31:11 +00:00
parent 0e69677dbc
commit b8d319a2fc
9 changed files with 34 additions and 5 deletions
+4 -2
View File
@@ -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
+4
View File
@@ -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)
+4
View File
@@ -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)
+4
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+1 -1
View File
@@ -55,7 +55,7 @@ public:
private:
static void caught(int signum);
static Slot m_handlers[HIGHEST_SIGNAL];
static Slot m_handlers[HIGHEST_SIGNAL];
};
#endif
+10
View File
@@ -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);
}
+3
View File
@@ -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();