diff --git a/src/Makefile.am b/src/Makefile.am index 33ab8891..5be6527a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -34,8 +34,6 @@ libsub_root_a_SOURCES = \ signal_handler.h \ thread_base.cc \ thread_base.h \ - thread_main.cc \ - thread_main.h \ thread_worker.cc \ thread_worker.h diff --git a/src/control.cc b/src/control.cc index 17aa6e81..29603594 100644 --- a/src/control.cc +++ b/src/control.cc @@ -114,7 +114,7 @@ Control::initialize() { m_ui->init(this); - m_inputStdin->insert(main_thread->poll()); + m_inputStdin->insert(torrent::main_thread()->poll()); } void @@ -124,7 +124,7 @@ Control::cleanup() { priority_queue_erase(&taskScheduler, &m_taskShutdown); - m_inputStdin->remove(main_thread->poll()); + m_inputStdin->remove(torrent::main_thread()->poll()); m_core->download_store()->disable(); diff --git a/src/core/curl_socket.cc b/src/core/curl_socket.cc index b8587edc..03b04e5f 100644 --- a/src/core/curl_socket.cc +++ b/src/core/curl_socket.cc @@ -41,6 +41,7 @@ #include #include +#include #include "control.h" @@ -69,22 +70,22 @@ CurlSocket::receive_socket(void* easy_handle, curl_socket_t fd, int what, void* if (socket == NULL) { socket = stack->new_socket(fd); - main_thread->poll()->open(socket); + torrent::main_thread()->poll()->open(socket); // No interface for libcurl to signal when it's interested in error events. // Assume that hence it must always be interested in them. - main_thread->poll()->insert_error(socket); + torrent::main_thread()->poll()->insert_error(socket); } if (what == CURL_POLL_NONE || what == CURL_POLL_OUT) - main_thread->poll()->remove_read(socket); + torrent::main_thread()->poll()->remove_read(socket); else - main_thread->poll()->insert_read(socket); + torrent::main_thread()->poll()->insert_read(socket); if (what == CURL_POLL_NONE || what == CURL_POLL_IN) - main_thread->poll()->remove_write(socket); + torrent::main_thread()->poll()->remove_write(socket); else - main_thread->poll()->insert_write(socket); + torrent::main_thread()->poll()->insert_write(socket); return 0; } @@ -99,7 +100,7 @@ CurlSocket::close() { if (m_fileDesc == -1) throw torrent::internal_error("CurlSocket::close() m_fileDesc == -1."); - main_thread->poll()->closed(this); + torrent::main_thread()->poll()->closed(this); m_fileDesc = -1; } diff --git a/src/globals.cc b/src/globals.cc index b0cb293a..a73230ef 100644 --- a/src/globals.cc +++ b/src/globals.cc @@ -43,6 +43,4 @@ rak::timer cachedTime; rpc::ip_table_list ip_tables; Control* control = NULL; -//__thread ThreadBase* main_thread = NULL; -ThreadMain* main_thread = NULL; ThreadWorker* worker_thread = NULL; diff --git a/src/globals.h b/src/globals.h index 2faea757..69d01f3f 100644 --- a/src/globals.h +++ b/src/globals.h @@ -41,7 +41,6 @@ #include #include "thread_base.h" -#include "thread_main.h" #include "thread_worker.h" #include "rpc/ip_table_list.h" @@ -57,8 +56,6 @@ extern rak::timer cachedTime; extern rpc::ip_table_list ip_tables; extern Control* control; -// extern __thread ThreadBase* main_thread; // Only use for worker threads for now. -extern ThreadMain* main_thread; extern ThreadWorker* worker_thread; #endif diff --git a/src/main.cc b/src/main.cc index 435c70e1..4cb89286 100644 --- a/src/main.cc +++ b/src/main.cc @@ -77,7 +77,6 @@ #include "signal_handler.h" #include "option_parser.h" -#include "thread_main.h" #include "thread_worker.h" void handle_sigbus(int signum, siginfo_t* sa, void* ptr); @@ -150,14 +149,29 @@ load_arg_torrents(Control* c, char** first, char** last) { } } -static inline rak::timer +static uint64_t client_next_timeout(Control* c) { if (taskScheduler.empty()) - return c->is_shutdown_started() ? rak::timer::from_milliseconds(100) : rak::timer::from_seconds(60); + return (c->is_shutdown_started() ? rak::timer::from_milliseconds(100) : rak::timer::from_seconds(60)).usec(); else if (taskScheduler.top()->time() <= cachedTime) return 0; else - return taskScheduler.top()->time() - cachedTime; + return (taskScheduler.top()->time() - cachedTime).usec(); +} + +static void +client_perform() { + // Use throw exclusively. + if (control->is_shutdown_completed()) + throw torrent::shutdown_exception(); + + if (control->is_shutdown_received()) + control->handle_shutdown(); + + control->inc_tick(); + + cachedTime = rak::timer::current(); + rak::priority_queue_perform(&taskScheduler, cachedTime); } int @@ -171,9 +185,6 @@ main(int argc, char** argv) { control = new Control; - main_thread = new ThreadMain(); - main_thread->init_thread(); - worker_thread = new ThreadWorker(); worker_thread->init_thread(); @@ -195,7 +206,11 @@ main(int argc, char** argv) { SignalHandler::set_handler(SIGUSR1, sigc::ptr_fun(&do_nothing)); torrent::Poll::slot_create_poll() = std::tr1::bind(&core::create_poll); - torrent::initialize(main_thread->poll()); + torrent::initialize(); + + torrent::main_thread()->init_thread(); + torrent::main_thread()->slot_do_work() = tr1::bind(&client_perform); + torrent::main_thread()->slot_next_timeout() = tr1::bind(&client_next_timeout, control); // Initialize option handlers after libtorrent to ensure // torrent::ConnectionManager* are valid etc. @@ -856,18 +871,7 @@ main(int argc, char** argv) { worker_thread->start_thread(); - while (!control->is_shutdown_completed()) { - if (control->is_shutdown_received()) - control->handle_shutdown(); - - control->inc_tick(); - - cachedTime = rak::timer::current(); - rak::priority_queue_perform(&taskScheduler, cachedTime); - - // Do shutdown check before poll, not after. - main_thread->poll()->do_poll(client_next_timeout(control).usec()); - } + torrent::thread_base::event_loop(torrent::main_thread()); control->core()->download_list()->session_save(); control->cleanup(); @@ -883,7 +887,6 @@ main(int argc, char** argv) { delete control; delete worker_thread; - delete main_thread; return 0; } diff --git a/src/thread_base.cc b/src/thread_base.cc index 0640cac6..19dab3b0 100644 --- a/src/thread_base.cc +++ b/src/thread_base.cc @@ -46,6 +46,7 @@ #include #include #include +#include #include #include "globals.h" @@ -167,7 +168,7 @@ ThreadBase::interrupt_main_polling() { int sleep_length = 0; while (ThreadBase::is_main_polling()) { - pthread_kill(main_thread->m_thread, SIGUSR1); + pthread_kill(torrent::main_thread()->pthread(), SIGUSR1); if (!ThreadBase::is_main_polling()) return; diff --git a/src/thread_main.cc b/src/thread_main.cc deleted file mode 100644 index 09c78989..00000000 --- a/src/thread_main.cc +++ /dev/null @@ -1,58 +0,0 @@ -// rTorrent - BitTorrent library -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - -#include "config.h" - -#include "thread_main.h" -#include "globals.h" - -#include -#include - -ThreadMain::~ThreadMain() { -} - -void -ThreadMain::init_thread() { - // The main thread always holds the lock while running. - acquire_global_lock(); - - m_poll = core::create_poll(); - m_poll->set_flags(torrent::Poll::flag_waive_global_lock); - - m_state = STATE_INITIALIZED; - m_thread = pthread_self(); -} diff --git a/src/thread_main.h b/src/thread_main.h deleted file mode 100644 index 39a7112e..00000000 --- a/src/thread_main.h +++ /dev/null @@ -1,57 +0,0 @@ -// rTorrent - BitTorrent library -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - -#ifndef RTORRENT_THREAD_MAIN_H -#define RTORRENT_THREAD_MAIN_H - -#include "thread_base.h" - -// Check if cacheline aligned with inheritance ends up taking two -// cachelines. - -class lt_cacheline_aligned ThreadMain : public ThreadBase { -public: - ThreadMain() {} - ~ThreadMain(); - - const char* name() const { return "main_rtorrent"; } - - virtual void init_thread(); - -private: -}; - -#endif