diff --git a/.gitignore b/.gitignore index 25d8dd5e..e260bc27 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,5 @@ scripts/ltoptions.m4 scripts/ltsugar.m4 scripts/ltversion.m4 scripts/lt~obsolete.m4 + +test/rtorrentTest diff --git a/Makefile.am b/Makefile.am index 8d021287..f3c8a930 100644 --- a/Makefile.am +++ b/Makefile.am @@ -17,7 +17,6 @@ EXTRA_DIST= \ rak/partial_queue.h \ rak/priority_queue.h \ rak/priority_queue_default.h \ - rak/ranges.h \ rak/regex.h \ rak/socket_address.h \ rak/string_manip.h \ diff --git a/autogen.sh b/autogen.sh index e4884f7a..79afab8e 100755 --- a/autogen.sh +++ b/autogen.sh @@ -6,7 +6,7 @@ echo aclocal... exit 1 } -aclocal -I ./scripts -I . ${ACLOCAL_FLAGS} +aclocal -I ./scripts -I . ${ACLOCAL_FLAGS} || exit 1 echo autoheader... (autoheader --version) < /dev/null > /dev/null 2>&1 || { @@ -14,16 +14,16 @@ echo autoheader... exit 1 } -autoheader +autoheader || exit 1 echo -n "libtoolize... " if ( (glibtoolize --version) < /dev/null > /dev/null 2>&1 ); then echo "using glibtoolize" - glibtoolize --automake --copy --force + glibtoolize --automake --copy --force || exit 1 elif ( (libtoolize --version) < /dev/null > /dev/null 2>&1 ) ; then echo "using libtoolize" - libtoolize --automake --copy --force + libtoolize --automake --copy --force || exit 1 else echo "libtoolize nor glibtoolize not found" @@ -36,7 +36,7 @@ echo automake... exit 1 } -automake --add-missing --copy --gnu +automake --add-missing --copy --gnu || exit 1 echo autoconf... (autoconf --version) < /dev/null > /dev/null 2>&1 || { @@ -44,7 +44,7 @@ echo autoconf... exit 1 } -autoconf +autoconf || exit 1 echo ready to configure diff --git a/configure.ac b/configure.ac index f8d4cbe9..8dbf6093 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT(rtorrent, 0.8.9, jaris@ifi.uio.no) +AC_INIT(rtorrent, 0.9.0, jaris@ifi.uio.no) AM_INIT_AUTOMAKE AM_CONFIG_HEADER(config.h) @@ -11,6 +11,8 @@ TORRENT_CHECK_CXXFLAGS() TORRENT_ENABLE_DEBUG() TORRENT_ENABLE_EXTRA_DEBUG() TORRENT_ENABLE_WERROR() +TORRENT_ENABLE_TR1() +TORRENT_ENABLE_CXX11() TORRENT_DISABLE_IPV6 @@ -27,9 +29,10 @@ TORRENT_WITHOUT_NCURSESW() TORRENT_WITHOUT_STATVFS() TORRENT_WITHOUT_STATFS() -ACX_PTHREAD(CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"; - LIBS="$PTHREAD_LIBS $LIBS" -) +ACX_PTHREAD() +CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS" +LIBS="$PTHREAD_LIBS $LIBS" PKG_CHECK_MODULES(sigc, sigc++-2.0, CXXFLAGS="$CXXFLAGS $sigc_CFLAGS"; @@ -39,7 +42,7 @@ PKG_CHECK_MODULES(libcurl, libcurl >= 7.15.4, CXXFLAGS="$CXXFLAGS $libcurl_CFLAGS"; LIBS="$LIBS $libcurl_LIBS") -PKG_CHECK_MODULES(libtorrent, libtorrent >= 0.12.9, +PKG_CHECK_MODULES(libtorrent, libtorrent >= 0.13.0, CXXFLAGS="$CXXFLAGS $libtorrent_CFLAGS"; LIBS="$LIBS $libtorrent_LIBS") diff --git a/rak/functional_fun.h b/rak/functional_fun.h index 30a6aeae..cc1ee5f2 100644 --- a/rak/functional_fun.h +++ b/rak/functional_fun.h @@ -53,6 +53,8 @@ #include #include +#include +#include namespace rak { @@ -96,13 +98,13 @@ public: bool is_valid() const { return m_base.get() != NULL; } - void set(base_type* base) { m_base = std::auto_ptr(base); } + void set(base_type* base) { m_base = std::tr1::shared_ptr(base); } base_type* release() { return m_base.release(); } Result operator () () { return (*m_base)(); } private: - std::auto_ptr m_base; + std::tr1::shared_ptr m_base; }; template @@ -113,13 +115,13 @@ public: bool is_valid() const { return m_base.get() != NULL; } - void set(base_type* base) { m_base = std::auto_ptr(base); } + void set(base_type* base) { m_base = std::tr1::shared_ptr(base); } base_type* release() { return m_base.release(); } Result operator () (Arg1 arg1) { return (*m_base)(arg1); } private: - std::auto_ptr m_base; + std::tr1::shared_ptr m_base; }; template @@ -130,13 +132,13 @@ public: bool is_valid() const { return m_base.get() != NULL; } - void set(base_type* base) { m_base = std::auto_ptr(base); } + void set(base_type* base) { m_base = std::tr1::shared_ptr(base); } base_type* release() { return m_base.release(); } Result operator () (Arg1 arg1, Arg2 arg2) { return (*m_base)(arg1, arg2); } private: - std::auto_ptr m_base; + std::tr1::shared_ptr m_base; }; template @@ -147,7 +149,7 @@ public: bool is_valid() const { return m_base.get() != NULL; } - void set(base_type* base) { m_base = std::auto_ptr(base); } + void set(base_type* base) { m_base = std::tr1::shared_ptr(base); } base_type* release() { return m_base.release(); } Result operator () (Arg2 arg2) { return (*m_base)(arg2); } @@ -156,7 +158,7 @@ public: Result operator () (Discard discard, Arg2 arg2) { return (*m_base)(arg2); } private: - std::auto_ptr m_base; + std::tr1::shared_ptr m_base; }; template @@ -167,13 +169,13 @@ public: bool is_valid() const { return m_base.get() != NULL; } - void set(base_type* base) { m_base = std::auto_ptr(base); } + void set(base_type* base) { m_base = std::tr1::shared_ptr(base); } base_type* release() { return m_base.release(); } Result operator () (Arg1 arg1, Arg2 arg2, Arg3 arg3) { return (*m_base)(arg1, arg2, arg3); } private: - std::auto_ptr m_base; + std::tr1::shared_ptr m_base; }; template diff --git a/rak/priority_queue_default.h b/rak/priority_queue_default.h index 0b4da804..f2d8902d 100644 --- a/rak/priority_queue_default.h +++ b/rak/priority_queue_default.h @@ -38,9 +38,8 @@ #define RAK_PRIORITY_QUEUE_DEFAULT_H #include +#include #include -#include -#include #include #include @@ -48,33 +47,34 @@ namespace rak { class priority_item { public: + typedef std::tr1::function slot_void; + priority_item() {} ~priority_item() { if (is_queued()) throw std::logic_error("priority_item::~priority_item() called on a queued item."); m_time = timer(); - m_slot.set(NULL); + m_slot = slot_void(); } - bool is_valid() const { return m_slot.is_valid(); } - bool is_queued() const { return m_time != timer(); } + bool is_valid() const { return (bool)m_slot; } + bool is_queued() const { return m_time != timer(); } - void call() { m_slot(); } - void set_slot(function0::base_type* s) { m_slot.set(s); } - - const timer& time() const { return m_time; } - void clear_time() { m_time = timer(); } - void set_time(const timer& t) { m_time = t; } + slot_void& slot() { return m_slot; } - bool compare(const timer& t) const { return m_time > t; } + const timer& time() const { return m_time; } + void clear_time() { m_time = timer(); } + void set_time(const timer& t) { m_time = t; } + + bool compare(const timer& t) const { return m_time > t; } private: priority_item(const priority_item&); void operator = (const priority_item&); timer m_time; - function0 m_slot; + slot_void m_slot; }; struct priority_compare { @@ -94,7 +94,7 @@ priority_queue_perform(priority_queue_default* queue, timer t) { queue->pop(); v->clear_time(); - v->call(); + v->slot()(); } } diff --git a/scripts/checks.m4 b/scripts/checks.m4 index 8a3de3a5..f32bd3b0 100644 --- a/scripts/checks.m4 +++ b/scripts/checks.m4 @@ -381,6 +381,30 @@ AC_DEFUN([TORRENT_CHECK_TR1], [ AC_LANG_POP(C++) ]) +AC_DEFUN([TORRENT_CHECK_CXX11], [ + AC_LANG_PUSH(C++) + AC_MSG_CHECKING(for C++11 support) + + AC_COMPILE_IFELSE( + [[#include + #include + class Foo; + typedef std::unordered_map Bar; + + union test { Bar b1; }; + ]], + [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_CXX11, 1, Define to 1 if your C++ compiler has support for C++11.) + ], + [ + AC_MSG_RESULT(no) + ] + ) + + AC_LANG_POP(C++) +]) + AC_DEFUN([TORRENT_WITH_FASTCGI], [ AC_ARG_WITH(fastcgi, [ --with-fastcgi=PATH Enable FastCGI RPC support. (DO NOT USE)], diff --git a/scripts/common.m4 b/scripts/common.m4 index 80bc090f..f875c71a 100644 --- a/scripts/common.m4 +++ b/scripts/common.m4 @@ -295,3 +295,18 @@ AC_DEFUN([TORRENT_ENABLE_TR1], [ TORRENT_CHECK_TR1() ]) ]) + +AC_DEFUN([TORRENT_ENABLE_CXX11], [ + AC_ARG_ENABLE(std_c++11, + [ --disable-std_c++11 disable check for support for C++11 [[default=enable]]], + [ + if test "$enableval" = "yes"; then + TORRENT_CHECK_CXX11() + else + AC_MSG_CHECKING(for C++11 support) + AC_MSG_RESULT(disabled) + fi + ],[ + TORRENT_CHECK_CXX11() + ]) +]) diff --git a/src/command_download.cc b/src/command_download.cc index 91c35443..bc58b9ac 100644 --- a/src/command_download.cc +++ b/src/command_download.cc @@ -138,10 +138,9 @@ apply_d_change_link(core::Download* download, const torrent::Object::list_type& switch (changeType) { case 0: - if (symlink(target.c_str(), link.c_str()) == -1) + // if (symlink(target.c_str(), link.c_str()) == -1) // control->core()->push_log("create_link failed: " + std::string(rak::error_number::current().c_str())); // control->core()->push_log("create_link failed: " + std::string(rak::error_number::current().c_str()) + " to " + target); - ; // Disabled. break; case 1: @@ -150,9 +149,9 @@ apply_d_change_link(core::Download* download, const torrent::Object::list_type& rak::error_number::clear_global(); if (!fileStat.update_link(link) || !fileStat.is_link() || - unlink(link.c_str()) == -1) - ; // control->core()->push_log("delete_link failed: " + std::string(rak::error_number::current().c_str())); - + unlink(link.c_str()) == -1) { + // control->core()->push_log("delete_link failed: " + std::string(rak::error_number::current().c_str())); + } break; } default: @@ -362,7 +361,7 @@ f_multicall(core::Download* download, const torrent::Object::list_type& args) { torrent::Object::list_type& row = result.insert(result.end(), torrent::Object::create_list())->as_list(); - for (torrent::Object::list_const_iterator cItr = ++args.begin(), cLast = args.end(); cItr != args.end(); cItr++) { + for (torrent::Object::list_const_iterator cItr = ++args.begin(); cItr != args.end(); cItr++) { const std::string& cmd = cItr->as_string(); row.push_back(rpc::parse_command(rpc::make_target(*itr), cmd.c_str(), cmd.c_str() + cmd.size()).first); } @@ -387,7 +386,7 @@ t_multicall(core::Download* download, const torrent::Object::list_type& args) { for (int itr = 0, last = download->tracker_list()->size(); itr != last; itr++) { torrent::Object::list_type& row = result.insert(result.end(), torrent::Object::create_list())->as_list(); - for (torrent::Object::list_const_iterator cItr = ++args.begin(), cLast = args.end(); cItr != args.end(); cItr++) { + for (torrent::Object::list_const_iterator cItr = ++args.begin(); cItr != args.end(); cItr++) { const std::string& cmd = cItr->as_string(); torrent::Tracker* t = download->tracker_list()->at(itr); @@ -415,7 +414,7 @@ p_multicall(core::Download* download, const torrent::Object::list_type& args) { itr != last; itr++) { torrent::Object::list_type& row = result.insert(result.end(), torrent::Object::create_list())->as_list(); - for (torrent::Object::list_const_iterator cItr = ++args.begin(), cLast = args.end(); cItr != args.end(); cItr++) { + for (torrent::Object::list_const_iterator cItr = ++args.begin(); cItr != args.end(); cItr++) { const std::string& cmd = cItr->as_string(); row.push_back(rpc::parse_command(rpc::make_target(*itr), cmd.c_str(), cmd.c_str() + cmd.size()).first); @@ -849,8 +848,8 @@ initialize_command_download() { // std::bind(&core::Download::main, std::placeholders::_1)), // CG_GROUP_INDEX())); - CMD2_DL ("d.group", std::bind(&cg_d_group, std::placeholders::_1));; - CMD2_DL ("d.group.name", std::bind(&cg_d_group, std::placeholders::_1));; + CMD2_DL ("d.group", std::bind(&cg_d_group, std::placeholders::_1)); + CMD2_DL ("d.group.name", std::bind(&cg_d_group, std::placeholders::_1)); CMD2_DL_V ("d.group.set", std::bind(&cg_d_group_set, std::placeholders::_1, std::placeholders::_2)); CMD2_DL ("d.initialize_logs", std::bind(&cmd_d_initialize_logs, std::placeholders::_1)); diff --git a/src/command_dynamic.cc b/src/command_dynamic.cc index db059251..013f855e 100644 --- a/src/command_dynamic.cc +++ b/src/command_dynamic.cc @@ -150,21 +150,21 @@ system_method_insert_object(const torrent::Object::list_type& args, int flags) { if (!(flags & rpc::object_storage::flag_private)) cmd_flags |= rpc::CommandMap::flag_public_xmlrpc; - rpc::object_storage::iterator obj_itr = control->object_storage()->insert_str(rawKey, value, flags); + control->object_storage()->insert_str(rawKey, value, flags); if ((flags & rpc::object_storage::mask_type) == rpc::object_storage::flag_function_type || (flags & rpc::object_storage::mask_type) == rpc::object_storage::flag_multi_type) { rpc::commands.insert_slot >::type> - (create_new_key<0>(rawKey, ""), + (create_new_key(rawKey), std::bind(&rpc::object_storage::call_function_str, control->object_storage(), - rawKey, std::placeholders::_1, std::placeholders::_2), + rawKey, std::placeholders::_1, std::placeholders::_2), &rpc::command_base_call, cmd_flags, NULL, NULL); } else { rpc::commands.insert_slot >::type> - (create_new_key<0>(rawKey, ""), + (create_new_key(rawKey), std::bind(&rpc::object_storage::get_str, control->object_storage(), rawKey), &rpc::command_base_call, cmd_flags, NULL, NULL); @@ -354,7 +354,7 @@ system_method_redirect(const torrent::Object::list_type& args) { std::string new_key = torrent::object_create_string(args.front()); std::string dest_key = torrent::object_create_string(args.back()); - rpc::commands.create_redirect(create_new_key<0>(new_key, ""), create_new_key<0>(dest_key, ""), + rpc::commands.create_redirect(create_new_key(new_key), create_new_key(dest_key), rpc::CommandMap::flag_public_xmlrpc | rpc::CommandMap::flag_delete_key | rpc::CommandMap::flag_modifiable); return torrent::Object(); diff --git a/src/command_events.cc b/src/command_events.cc index 08a6be7d..6b11537d 100644 --- a/src/command_events.cc +++ b/src/command_events.cc @@ -297,7 +297,7 @@ d_multicall(const torrent::Object::list_type& args) { for (core::Download** vItr = dlist; vItr != dlist + dlist_size; vItr++) { torrent::Object::list_type& row = result.insert(result.end(), torrent::Object::create_list())->as_list(); - for (torrent::Object::list_const_iterator cItr = ++args.begin(), cLast = args.end(); cItr != args.end(); cItr++) { + for (torrent::Object::list_const_iterator cItr = ++args.begin(); cItr != args.end(); cItr++) { const std::string& cmd = cItr->as_string(); row.push_back(rpc::parse_command(rpc::make_target(*vItr), cmd.c_str(), cmd.c_str() + cmd.size()).first); } diff --git a/src/command_helpers.h b/src/command_helpers.h index 59053ebe..b215ec2e 100644 --- a/src/command_helpers.h +++ b/src/command_helpers.h @@ -41,6 +41,10 @@ #include "rpc/parse_commands.h" #include "rpc/object_storage.h" +#ifndef HAVE_CXX11 +namespace std { using namespace tr1; } +#endif + void initialize_commands(); // @@ -98,41 +102,41 @@ void initialize_commands(); #define CMD2_VAR_BOOL(key, value) \ control->object_storage()->insert_c_str(key, int64_t(value), rpc::object_storage::flag_bool_type); \ - CMD2_ANY(key, std::bind(&rpc::object_storage::get, control->object_storage(), \ + CMD2_ANY(key, std::bind(&rpc::object_storage::get, control->object_storage(), \ torrent::raw_string::from_c_str(key))); \ CMD2_ANY_VALUE(key ".set", std::bind(&rpc::object_storage::set_bool, control->object_storage(), \ torrent::raw_string::from_c_str(key), std::placeholders::_2)); #define CMD2_VAR_VALUE(key, value) \ control->object_storage()->insert_c_str(key, int64_t(value), rpc::object_storage::flag_value_type); \ - CMD2_ANY(key, std::bind(&rpc::object_storage::get, control->object_storage(), \ + CMD2_ANY(key, std::bind(&rpc::object_storage::get, control->object_storage(), \ torrent::raw_string::from_c_str(key))); \ CMD2_ANY_VALUE(key ".set", std::bind(&rpc::object_storage::set_value, control->object_storage(), \ torrent::raw_string::from_c_str(key), std::placeholders::_2)); #define CMD2_VAR_STRING(key, value) \ control->object_storage()->insert_c_str(key, value, rpc::object_storage::flag_string_type); \ - CMD2_ANY(key, std::bind(&rpc::object_storage::get, control->object_storage(), \ + CMD2_ANY(key, std::bind(&rpc::object_storage::get, control->object_storage(), \ torrent::raw_string::from_c_str(key))); \ CMD2_ANY_STRING(key ".set", std::bind(&rpc::object_storage::set_string, control->object_storage(), \ - torrent::raw_string::from_c_str(key), std::placeholders::_2)); + torrent::raw_string::from_c_str(key), std::placeholders::_2)); #define CMD2_VAR_C_STRING(key, value) \ control->object_storage()->insert_c_str(key, value, rpc::object_storage::flag_string_type); \ - CMD2_ANY(key, std::bind(&rpc::object_storage::get, control->object_storage(), \ + CMD2_ANY(key, std::bind(&rpc::object_storage::get, control->object_storage(), \ torrent::raw_string::from_c_str(key))); #define CMD2_VAR_LIST(key) \ control->object_storage()->insert_c_str(key, torrent::Object::create_list(), rpc::object_storage::flag_list_type); \ - CMD2_ANY(key, std::bind(&rpc::object_storage::get, control->object_storage(), \ + CMD2_ANY(key, std::bind(&rpc::object_storage::get, control->object_storage(), \ torrent::raw_string::from_c_str(key))); \ CMD2_ANY_LIST(key ".set", std::bind(&rpc::object_storage::set_list, control->object_storage(), \ - torrent::raw_string::from_c_str(key), std::placeholders::_2)); \ + torrent::raw_string::from_c_str(key), std::placeholders::_2)); \ CMD2_ANY_VOID(key ".push_back", std::bind(&rpc::object_storage::list_push_back, control->object_storage(), \ - torrent::raw_string::from_c_str(key), std::placeholders::_2)); + torrent::raw_string::from_c_str(key), std::placeholders::_2)); -#define CMD2_FUNC_SINGLE(key, cmds) \ +#define CMD2_FUNC_SINGLE(key, cmds) \ CMD2_ANY(key, std::bind(&rpc::command_function_call, torrent::raw_string::from_c_str(cmds), \ std::placeholders::_1, std::placeholders::_2)); @@ -148,11 +152,11 @@ void initialize_commands(); rpc::commands.create_redirect(from_key, to_key, rpc::CommandMap::flag_public_xmlrpc | rpc::CommandMap::flag_tracker_target | rpc::CommandMap::flag_dont_delete); #define CMD2_REDIRECT_GENERIC_STR(from_key, to_key) \ - rpc::commands.create_redirect(create_new_key<0>(from_key, ""), create_new_key<0>(to_key, ""), \ + rpc::commands.create_redirect(create_new_key(from_key), create_new_key(to_key), \ rpc::CommandMap::flag_public_xmlrpc | rpc::CommandMap::flag_no_target | rpc::CommandMap::flag_delete_key); #define CMD2_REDIRECT_GENERIC_STR_NO_EXPORT(from_key, to_key) \ - rpc::commands.create_redirect(create_new_key<0>(from_key, ""), create_new_key<0>(to_key, ""), \ + rpc::commands.create_redirect(create_new_key(from_key), create_new_key(to_key), \ rpc::CommandMap::flag_no_target | rpc::CommandMap::flag_delete_key); // @@ -175,7 +179,11 @@ struct object_convert_type { template torrent::Object operator () (Arg1& arg1) { m_slot(arg1); return torrent::Object(); } template + torrent::Object operator () (const Arg1& arg1) { m_slot(arg1); return torrent::Object(); } + template torrent::Object operator () (Arg1& arg1, Arg2& arg2) { m_slot(arg1, arg2); return torrent::Object(); } + template + torrent::Object operator () (const Arg1& arg1, const Arg2& arg2) { m_slot(arg1, arg2); return torrent::Object(); } Functor m_slot; }; @@ -197,4 +205,11 @@ create_new_key(const std::string& key, const char postfix[postfix_size]) { return buffer; } +inline const char* +create_new_key(const std::string& key) { + char *buffer = new char[key.size() + 1]; + std::memcpy(buffer, key.c_str(), key.size() + 1); + return buffer; +} + #endif diff --git a/src/command_ip.cc b/src/command_ip.cc index b10a279b..b92547df 100644 --- a/src/command_ip.cc +++ b/src/command_ip.cc @@ -187,8 +187,6 @@ apply_ipv4_filter_load(const torrent::Object::list_type& args) { if (args.size() != 2) throw torrent::input_error("Incorrect number of arguments."); - torrent::Object::list_const_iterator args_itr = args.begin(); - std::fstream file(rak::path_expand(args.front().as_string()).c_str(), std::ios::in); if (!file.is_open()) diff --git a/src/command_network.cc b/src/command_network.cc index 05b00410..b513b068 100644 --- a/src/command_network.cc +++ b/src/command_network.cc @@ -62,6 +62,8 @@ #include "control.h" #include "command_helpers.h" +namespace tr1 { using namespace std::tr1; } + torrent::Object apply_encryption(const torrent::Object::list_type& args) { uint32_t options_mask = torrent::ConnectionManager::encryption_none; @@ -92,8 +94,6 @@ apply_tos(const torrent::Object::string_type& arg) { return torrent::Object(); } -torrent::Object apply_hash_read_ahead(int arg) { torrent::set_hash_read_ahead(arg << 20); return torrent::Object(); } -torrent::Object apply_hash_interval(int arg) { torrent::set_hash_interval(arg * 1000); return torrent::Object(); } torrent::Object apply_encoding_list(const std::string& arg) { torrent::encoding_list()->push_back(arg); return torrent::Object(); } torrent::File* @@ -126,10 +126,10 @@ xmlrpc_find_peer(core::Download* download, const torrent::HashString& hash) { void initialize_xmlrpc() { rpc::xmlrpc.initialize(); - rpc::xmlrpc.set_slot_find_download(rak::mem_fn(control->core()->download_list(), &core::DownloadList::find_hex_ptr)); - rpc::xmlrpc.set_slot_find_file(rak::ptr_fn(&xmlrpc_find_file)); - rpc::xmlrpc.set_slot_find_tracker(rak::ptr_fn(&xmlrpc_find_tracker)); - rpc::xmlrpc.set_slot_find_peer(rak::ptr_fn(&xmlrpc_find_peer)); + rpc::xmlrpc.slot_find_download() = tr1::bind(&core::DownloadList::find_hex_ptr, control->core()->download_list(), tr1::placeholders::_1); + rpc::xmlrpc.slot_find_file() = tr1::bind(&xmlrpc_find_file, tr1::placeholders::_1, tr1::placeholders::_2); + rpc::xmlrpc.slot_find_tracker() = tr1::bind(&xmlrpc_find_tracker, tr1::placeholders::_1, tr1::placeholders::_2); + rpc::xmlrpc.slot_find_peer() = tr1::bind(&xmlrpc_find_peer, tr1::placeholders::_1, tr1::placeholders::_2); unsigned int count = 0; @@ -303,11 +303,4 @@ initialize_command_network() { CMD2_ANY_STRING ("network.xmlrpc.dialect.set", std::bind(&apply_xmlrpc_dialect, std::placeholders::_2)); CMD2_ANY ("network.xmlrpc.size_limit", std::bind(&rpc::XmlRpc::size_limit)); CMD2_ANY_VALUE_V ("network.xmlrpc.size_limit.set", std::bind(&rpc::XmlRpc::set_size_limit, std::placeholders::_2)); - - CMD2_ANY ("system.hash.read_ahead", std::bind(&torrent::hash_read_ahead)); - CMD2_ANY_VALUE_V ("system.hash.read_ahead.set", std::bind(&apply_hash_read_ahead, std::placeholders::_2)); - CMD2_ANY ("system.hash.interval", std::bind(&torrent::hash_interval)); - CMD2_ANY_VALUE_V ("system.hash.interval.set", std::bind(&apply_hash_interval, std::placeholders::_2)); - CMD2_ANY ("system.hash.max_tries", std::bind(&torrent::hash_max_tries)); - CMD2_ANY_VALUE_V ("system.hash.max_tries.set", std::bind(&torrent::set_hash_max_tries, std::placeholders::_2)); } diff --git a/src/command_throttle.cc b/src/command_throttle.cc index f2e89e1e..c2c6344c 100644 --- a/src/command_throttle.cc +++ b/src/command_throttle.cc @@ -89,7 +89,7 @@ parse_address_range(const torrent::Object::list_type& args, torrent::Object::lis // convert to [begin, end) making sure the end doesn't overflow // (this precludes 255.255.255.255 from ever matching, but that's not a real IP anyway) - return std::make_pair(begin, std::max(end, end + 1)); + return std::make_pair((uint32_t)begin, (uint32_t)std::max(end, end + 1)); } torrent::Object diff --git a/src/control.cc b/src/control.cc index acf51e9e..17aa6e81 100644 --- a/src/control.cc +++ b/src/control.cc @@ -77,7 +77,7 @@ Control::Control() : m_inputStdin->slot_pressed(sigc::mem_fun(m_input, &input::Manager::pressed)); - m_taskShutdown.set_slot(rak::mem_fn(this, &Control::handle_shutdown)); + m_taskShutdown.slot() = std::tr1::bind(&Control::handle_shutdown, this); m_commandScheduler->set_slot_error_message(rak::mem_fn(m_core, &core::Manager::push_log_std)); } diff --git a/src/core/Makefile.am b/src/core/Makefile.am index fe07cbfe..57a2a49f 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -26,12 +26,6 @@ libsub_core_a_SOURCES = \ manager.h \ poll_manager.cc \ poll_manager.h \ - poll_manager_epoll.cc \ - poll_manager_epoll.h \ - poll_manager_kqueue.cc \ - poll_manager_kqueue.h \ - poll_manager_select.cc \ - poll_manager_select.h \ range_map.h \ view.cc \ view.h \ diff --git a/src/core/curl_get.cc b/src/core/curl_get.cc index fe1077ef..fe9f8d62 100644 --- a/src/core/curl_get.cc +++ b/src/core/curl_get.cc @@ -82,7 +82,7 @@ CurlGet::start() { // Normally libcurl should handle the timeout. But sometimes that doesn't // work right so we do a fallback timeout that just aborts the transfer. - m_taskTimeout.set_slot(rak::mem_fn(this, &CurlGet::receive_timeout)); + m_taskTimeout.slot() = std::tr1::bind(&CurlGet::receive_timeout, this); priority_queue_erase(&taskScheduler, &m_taskTimeout); priority_queue_insert(&taskScheduler, &m_taskTimeout, cachedTime + rak::timer::from_seconds(m_timeout + 5)); } diff --git a/src/core/curl_stack.cc b/src/core/curl_stack.cc index e8c15c6b..2153ab24 100644 --- a/src/core/curl_stack.cc +++ b/src/core/curl_stack.cc @@ -46,8 +46,6 @@ #include "curl_socket.h" #include "curl_stack.h" -namespace std { using namespace tr1; } - namespace core { CurlStack::CurlStack() : @@ -57,7 +55,7 @@ CurlStack::CurlStack() : m_ssl_verify_peer(true), m_dns_timeout(60) { - m_taskTimeout.set_slot(rak::mem_fn(this, &CurlStack::receive_timeout)); + m_taskTimeout.slot() = std::tr1::bind(&CurlStack::receive_timeout, this); #if (LIBCURL_VERSION_NUM >= 0x071000) curl_multi_setopt((CURLM*)m_handle, CURLMOPT_TIMERDATA, this); diff --git a/src/core/dht_manager.cc b/src/core/dht_manager.cc index aaea8263..0472d686 100644 --- a/src/core/dht_manager.cc +++ b/src/core/dht_manager.cc @@ -114,7 +114,7 @@ DhtManager::start_dht() { torrent::dht_manager()->start(port); torrent::dht_manager()->reset_statistics(); - m_updateTimeout.set_slot(rak::mem_fn(this, &DhtManager::update)); + m_updateTimeout.slot() = std::tr1::bind(&DhtManager::update, this); priority_queue_insert(&taskScheduler, &m_updateTimeout, (cachedTime + rak::timer::from_seconds(60)).round_seconds()); m_dhtPrevCycle = 0; @@ -197,7 +197,7 @@ DhtManager::update() { break; if (itr == end) { - m_stopTimeout.set_slot(rak::mem_fn(this, &DhtManager::stop_dht)); + m_stopTimeout.slot() = std::tr1::bind(&DhtManager::stop_dht, this); priority_queue_insert(&taskScheduler, &m_stopTimeout, (cachedTime + rak::timer::from_seconds(15 * 60)).round_seconds()); } } diff --git a/src/core/download_factory.cc b/src/core/download_factory.cc index 45fc3c95..3f63dc4b 100644 --- a/src/core/download_factory.cc +++ b/src/core/download_factory.cc @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -105,8 +106,8 @@ DownloadFactory::DownloadFactory(Manager* m) : m_printLog(true), m_isFile(false) { - m_taskLoad.set_slot(rak::mem_fn(this, &DownloadFactory::receive_load)); - m_taskCommit.set_slot(rak::mem_fn(this, &DownloadFactory::receive_commit)); + m_taskLoad.slot() = std::tr1::bind(&DownloadFactory::receive_load, this); + m_taskCommit.slot() = std::tr1::bind(&DownloadFactory::receive_commit, this); // m_variables["connection_leech"] = rpc::call_command_void("protocol.connection.leech"); // m_variables["connection_seed"] = rpc::call_command_void("protocol.connection.seed"); @@ -156,8 +157,8 @@ DownloadFactory::receive_load() { m_stream = new std::stringstream; HttpQueue::iterator itr = m_manager->http_queue()->insert(m_uri, m_stream); - (*itr)->signal_done().push_front(std::bind(&DownloadFactory::receive_loaded, this)); - (*itr)->signal_failed().push_front(std::bind(&DownloadFactory::receive_failed, this, std::placeholders::_1)); + (*itr)->signal_done().push_front(std::tr1::bind(&DownloadFactory::receive_loaded, this)); + (*itr)->signal_failed().push_front(std::tr1::bind(&DownloadFactory::receive_failed, this, std::tr1::placeholders::_1)); m_variables["tied_to_file"] = (int64_t)false; diff --git a/src/core/download_list.cc b/src/core/download_list.cc index 939e6ff7..97560d02 100644 --- a/src/core/download_list.cc +++ b/src/core/download_list.cc @@ -179,8 +179,8 @@ DownloadList::insert(Download* download) { iterator itr = base_type::insert(end(), download); try { - (*itr)->data()->slot_initial_hash() = std::bind(&DownloadList::hash_done, this, download); - (*itr)->data()->slot_download_done() = std::bind(&DownloadList::received_finished, this, download); + (*itr)->data()->slot_initial_hash() = tr1::bind(&DownloadList::hash_done, this, download); + (*itr)->data()->slot_download_done() = tr1::bind(&DownloadList::received_finished, this, download); // This needs to be separated into two different calls to ensure // the download remains in the view. @@ -642,6 +642,9 @@ DownloadList::confirm_finished(Download* download) { DL_TRIGGER_EVENT(download, "event.download.finished"); + if (find(infohash) != end()) + return; + // if (download->resume_flags() != ~uint32_t()) // throw torrent::internal_error("DownloadList::confirm_finished(...) download->resume_flags() != ~uint32_t()."); @@ -655,8 +658,7 @@ DownloadList::confirm_finished(Download* download) { // being hashed. download->set_resume_flags(~uint32_t()); - if (find(infohash) != end() && - !download->is_active() && rpc::call_command_value("d.state", rpc::make_target(download)) == 1) + if (!download->is_active() && rpc::call_command_value("d.state", rpc::make_target(download)) == 1) resume(download, torrent::Download::start_no_create | torrent::Download::start_skip_tracker | diff --git a/src/core/http_queue.cc b/src/core/http_queue.cc index 5c3d6958..76b2a659 100644 --- a/src/core/http_queue.cc +++ b/src/core/http_queue.cc @@ -46,8 +46,6 @@ #include "http_queue.h" #include "curl_get.h" -namespace std { using namespace tr1; } - namespace core { HttpQueue::iterator @@ -60,8 +58,8 @@ HttpQueue::insert(const std::string& url, std::iostream* s) { iterator itr = Base::insert(end(), h.get()); - h->signal_done().push_back(std::bind(&HttpQueue::erase, this, itr)); - h->signal_failed().push_back(std::bind(&HttpQueue::erase, this, itr)); + h->signal_done().push_back(std::tr1::bind(&HttpQueue::erase, this, itr)); + h->signal_failed().push_back(std::tr1::bind(&HttpQueue::erase, this, itr)); (*itr)->start(); diff --git a/src/core/manager.cc b/src/core/manager.cc index d36e78fa..5ccf572a 100644 --- a/src/core/manager.cc +++ b/src/core/manager.cc @@ -71,13 +71,9 @@ #include "download_store.h" #include "http_queue.h" #include "manager.h" -#include "poll_manager_epoll.h" -#include "poll_manager_kqueue.h" -#include "poll_manager_select.h" +#include "poll_manager.h" #include "view.h" -namespace std { using namespace tr1; } - namespace core { void @@ -206,7 +202,7 @@ Manager::get_address_throttle(const sockaddr* addr) { // Most of this should be possible to move out. void Manager::initialize_second() { - torrent::Http::set_factory(std::bind(&CurlStack::new_object, m_httpStack)); + torrent::Http::slot_factory() = std::tr1::bind(&CurlStack::new_object, m_httpStack); m_httpQueue->slot_factory(sigc::mem_fun(m_httpStack, &CurlStack::new_object)); CurlStack::global_init(); diff --git a/src/core/poll_manager.cc b/src/core/poll_manager.cc index 85d7de79..1023b0f1 100644 --- a/src/core/poll_manager.cc +++ b/src/core/poll_manager.cc @@ -38,72 +38,56 @@ #include #include -#include +#include +#include +#include +#include #include "globals.h" #include "control.h" #include "manager.h" #include "poll_manager.h" -#include "poll_manager_epoll.h" -#include "poll_manager_kqueue.h" -#include "poll_manager_select.h" namespace core { -PollManager::PollManager(torrent::Poll* poll) : - m_poll(poll) { - - if (m_poll == NULL) - throw std::logic_error("PollManager::PollManager(...) received poll == NULL"); -} - -PollManager::~PollManager() { - delete m_poll; -} - -PollManager* -PollManager::create_poll_manager() { - PollManager* pollManager = NULL; +torrent::Poll* +create_poll() { Log* log = &control->core()->get_log_important(); - const char* poll = getenv("RTORRENT_POLL"); + const char* poll_name = getenv("RTORRENT_POLL"); int maxOpen = sysconf(_SC_OPEN_MAX); - if (poll != NULL) { - if (!strcmp(poll, "epoll")) - pollManager = PollManagerEPoll::create(maxOpen); - else if (!strcmp(poll, "kqueue")) - pollManager = PollManagerKQueue::create(maxOpen); - else if (!strcmp(poll, "select")) - pollManager = PollManagerSelect::create(maxOpen); + torrent::Poll* poll = NULL; - if (pollManager == NULL) - log->push_front(std::string("Cannot enable '") + poll + "' based polling."); + if (poll_name != NULL) { + if (!strcmp(poll_name, "epoll")) + poll = torrent::PollEPoll::create(maxOpen); + else if (!strcmp(poll_name, "kqueue")) + poll = torrent::PollKQueue::create(maxOpen); + else if (!strcmp(poll_name, "select")) + poll = torrent::PollSelect::create(maxOpen); + + if (poll == NULL) + log->push_front(std::string("Cannot enable '") + poll_name + "' based polling."); } - if (pollManager != NULL) - log->push_front(std::string("Using '") + poll + "' based polling."); + if (poll != NULL) + log->push_front(std::string("Using '") + poll_name + "' based polling."); - else if ((pollManager = PollManagerEPoll::create(maxOpen)) != NULL) + else if ((poll = torrent::PollEPoll::create(maxOpen)) != NULL) log->push_front("Using 'epoll' based polling."); - else if ((pollManager = PollManagerKQueue::create(maxOpen)) != NULL) + else if ((poll = torrent::PollKQueue::create(maxOpen)) != NULL) log->push_front("Using 'kqueue' based polling."); - else if ((pollManager = PollManagerSelect::create(maxOpen)) != NULL) + else if ((poll = torrent::PollSelect::create(maxOpen)) != NULL) log->push_front("Using 'select' based polling."); else - throw std::runtime_error("Could not create any PollManager."); + throw torrent::internal_error("Could not create any Poll object."); - return pollManager; -} - -void -PollManager::check_error() { - if (rak::error_number::current().value() != rak::error_number::e_intr) - throw std::runtime_error("Poll::work(): " + std::string(rak::error_number::current().c_str())); + return poll; } } diff --git a/src/core/poll_manager.h b/src/core/poll_manager.h index 5b9e6507..bdbf5a0e 100644 --- a/src/core/poll_manager.h +++ b/src/core/poll_manager.h @@ -37,41 +37,15 @@ #ifndef RTORRENT_CORE_POLL_MANAGER_H #define RTORRENT_CORE_POLL_MANAGER_H -#include -#include -#include - #include "curl_stack.h" +namespace torrent { +class Poll; +} + namespace core { -// CurlStack really should be somewhere else, but that won't happen -// until they add an epoll friendly API. - -class PollManager { -public: - typedef sigc::signal0 Signal; - - PollManager(torrent::Poll* poll); - virtual ~PollManager(); - - unsigned int get_open_max() const { return m_poll->open_max(); } - - torrent::Poll* get_torrent_poll() { return m_poll; } - - virtual void poll(rak::timer timeout) = 0; - virtual void poll_simple(rak::timer timeout) = 0; - - static PollManager* create_poll_manager(); - -protected: - PollManager(const PollManager&); - void operator = (const PollManager&); - - void check_error(); - - torrent::Poll* m_poll; -}; +torrent::Poll* create_poll(); } diff --git a/src/core/poll_manager_epoll.cc b/src/core/poll_manager_epoll.cc deleted file mode 100644 index 8b7670db..00000000 --- a/src/core/poll_manager_epoll.cc +++ /dev/null @@ -1,98 +0,0 @@ -// rTorrent - BitTorrent client -// 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 -#include -#include -#include -#include -#include - -#include "poll_manager_epoll.h" -#include "thread_base.h" - -namespace core { - -PollManagerEPoll* -PollManagerEPoll::create(int maxOpenSockets) { - torrent::PollEPoll* p = torrent::PollEPoll::create(maxOpenSockets); - - if (p == NULL) - return NULL; - else - return new PollManagerEPoll(p); -} - -PollManagerEPoll::~PollManagerEPoll() { -} - -void -PollManagerEPoll::poll(rak::timer timeout) { - // Add 1ms to ensure we don't idle loop due to the lack of - // resolution. - torrent::perform(); - timeout = std::min(timeout, rak::timer(torrent::next_timeout())) + 1000; - - ThreadBase::release_global_lock(); - ThreadBase::entering_main_polling(); - - int status = static_cast(m_poll)->poll((timeout.usec() + 999) / 1000); - - ThreadBase::leaving_main_polling(); - ThreadBase::acquire_global_lock(); - - if (status == -1) - return check_error(); - - torrent::perform(); - static_cast(m_poll)->perform(); -} - -void -PollManagerEPoll::poll_simple(rak::timer timeout) { - // Add 1ms to ensure we don't idle loop due to the lack of - // resolution. - timeout = timeout + 1000; - - if (static_cast(m_poll)->poll((timeout.usec() + 999) / 1000) == -1) - return check_error(); - - static_cast(m_poll)->perform(); -} - -} diff --git a/src/core/poll_manager_epoll.h b/src/core/poll_manager_epoll.h deleted file mode 100644 index b000c640..00000000 --- a/src/core/poll_manager_epoll.h +++ /dev/null @@ -1,64 +0,0 @@ -// rTorrent - BitTorrent client -// 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_CORE_POLL_MANAGER_EPOLL_H -#define RTORRENT_CORE_POLL_MANAGER_EPOLL_H - -#include "poll_manager.h" - -namespace torrent { - class PollEPoll; -} - -namespace core { - -class PollManagerEPoll : public PollManager { -public: - static PollManagerEPoll* create(int maxOpenSockets); - ~PollManagerEPoll(); - - torrent::Poll* get_torrent_poll(); - - void poll(rak::timer timeout); - void poll_simple(rak::timer timeout); - -private: - PollManagerEPoll(torrent::Poll* p) : PollManager(p) {} -}; - -} - -#endif diff --git a/src/core/poll_manager_kqueue.cc b/src/core/poll_manager_kqueue.cc deleted file mode 100644 index 5bf309e7..00000000 --- a/src/core/poll_manager_kqueue.cc +++ /dev/null @@ -1,99 +0,0 @@ -// rTorrent - BitTorrent client -// 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 -#include -#include -#include -#include -#include -#include - -#include "poll_manager_kqueue.h" -#include "thread_base.h" - -namespace core { - -PollManagerKQueue* -PollManagerKQueue::create(int maxOpenSockets) { - torrent::PollKQueue* p = torrent::PollKQueue::create(maxOpenSockets); - - if (p == NULL) - return NULL; - else - return new PollManagerKQueue(p); -} - -PollManagerKQueue::~PollManagerKQueue() { -} - -void -PollManagerKQueue::poll(rak::timer timeout) { - // Add 1ms to ensure we don't idle loop due to the lack of - // resolution. - torrent::perform(); - timeout = std::min(timeout, rak::timer(torrent::next_timeout())) + 1000; - - ThreadBase::release_global_lock(); - ThreadBase::entering_main_polling(); - - int status = static_cast(m_poll)->poll((timeout.usec() + 999) / 1000); - - ThreadBase::leaving_main_polling(); - ThreadBase::acquire_global_lock(); - - if (status == -1) - return check_error(); - - torrent::perform(); - static_cast(m_poll)->perform(); -} - -void -PollManagerKQueue::poll_simple(rak::timer timeout) { - // Add 1ms to ensure we don't idle loop due to the lack of - // resolution. - timeout = std::min(timeout, rak::timer(torrent::next_timeout())) + 1000; - - if (static_cast(m_poll)->poll((timeout.usec() + 999) / 1000) == -1) - return check_error(); - - static_cast(m_poll)->perform(); -} - -} diff --git a/src/core/poll_manager_kqueue.h b/src/core/poll_manager_kqueue.h deleted file mode 100644 index 1c3bd0b9..00000000 --- a/src/core/poll_manager_kqueue.h +++ /dev/null @@ -1,64 +0,0 @@ -// rTorrent - BitTorrent client -// 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_CORE_POLL_MANAGER_KQUEUE_H -#define RTORRENT_CORE_POLL_MANAGER_KQUEUE_H - -#include "poll_manager.h" - -namespace torrent { - class PollKQueue; -} - -namespace core { - -class PollManagerKQueue : public PollManager { -public: - static PollManagerKQueue* create(int maxOpenSockets); - ~PollManagerKQueue(); - - torrent::Poll* get_torrent_poll(); - - void poll(rak::timer timeout); - void poll_simple(rak::timer timeout); - -private: - PollManagerKQueue(torrent::Poll* p) : PollManager(p) {} -}; - -} - -#endif diff --git a/src/core/poll_manager_select.cc b/src/core/poll_manager_select.cc deleted file mode 100644 index 70d9fd1d..00000000 --- a/src/core/poll_manager_select.cc +++ /dev/null @@ -1,127 +0,0 @@ -// rTorrent - BitTorrent client -// 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 -#include -#include -#include -#include -#include -#include -#include - -#include "poll_manager_select.h" -#include "thread_base.h" - -namespace core { - -PollManagerSelect::PollManagerSelect(torrent::Poll* p) : PollManager(p) { -#if defined USE_VARIABLE_FDSET - m_setSize = (m_poll->open_max() + 7) / 8; - - char* buffer = rak::cacheline_allocator::alloc_size(3 * m_setSize); - std::memset(buffer, 0, 3 * m_setSize); - - m_readSet = (fd_set*)buffer; - m_writeSet = (fd_set*)(buffer += m_setSize); - m_errorSet = (fd_set*)(buffer += m_setSize); -#else -#error Only variable fdset supported atm. -#endif -} - -PollManagerSelect* -PollManagerSelect::create(int maxOpenSockets) { - torrent::PollSelect* p = torrent::PollSelect::create(maxOpenSockets); - - if (p == NULL) - return NULL; - - return new PollManagerSelect(p); -} - -PollManagerSelect::~PollManagerSelect() { - free(m_readSet); -} - -void -PollManagerSelect::poll(rak::timer timeout) { - torrent::perform(); - timeout = std::min(timeout, rak::timer(torrent::next_timeout())) + 1000; - - std::memset(m_readSet, 0, m_setSize); - std::memset(m_writeSet, 0, m_setSize); - std::memset(m_errorSet, 0, m_setSize); - - unsigned int maxFd = static_cast(m_poll)->fdset(m_readSet, m_writeSet, m_errorSet); - - 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) - return check_error(); - - torrent::perform(); - static_cast(m_poll)->perform(m_readSet, m_writeSet, m_errorSet); -} - -void -PollManagerSelect::poll_simple(rak::timer timeout) { - torrent::PollSelect* currentPoll = static_cast(m_poll); - - timeout = timeout + 1000; - std::memset(m_readSet, 0, 3 * m_setSize); - - unsigned int maxFd = currentPoll->fdset(m_readSet, m_writeSet, m_errorSet); - - timeval t = timeout.tval(); - - if (select(maxFd + 1, m_readSet, m_writeSet, m_errorSet, &t) == -1) - return check_error(); - - currentPoll->perform(m_readSet, m_writeSet, m_errorSet); -} - -} diff --git a/src/core/poll_manager_select.h b/src/core/poll_manager_select.h deleted file mode 100644 index 8aa46e43..00000000 --- a/src/core/poll_manager_select.h +++ /dev/null @@ -1,67 +0,0 @@ -// rTorrent - BitTorrent client -// 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_CORE_POLL_MANAGER_SELECT_H -#define RTORRENT_CORE_POLL_MANAGER_SELECT_H - -#include "poll_manager.h" - -namespace torrent { - class PollSelect; -} - -namespace core { - -class lt_cacheline_aligned PollManagerSelect : public PollManager { -public: - static PollManagerSelect* create(int maxOpenSockets); - ~PollManagerSelect(); - - void poll(rak::timer timeout); - void poll_simple(rak::timer timeout); - -private: - PollManagerSelect(torrent::Poll* p); - - unsigned int m_setSize; - fd_set* m_readSet; - fd_set* m_writeSet; - fd_set* m_errorSet; -}; - -} - -#endif diff --git a/src/core/view.cc b/src/core/view.cc index d028f126..8f637396 100644 --- a/src/core/view.cc +++ b/src/core/view.cc @@ -172,7 +172,7 @@ View::initialize(const std::string& name) { m_focus = 0; set_last_changed(rak::timer()); - m_delayChanged.set_slot(rak::mem_fn(&m_signalChanged, &signal_type::operator())); + m_delayChanged.slot() = std::tr1::bind(&signal_type::operator(), &m_signalChanged); } void diff --git a/src/core/view.h b/src/core/view.h index a5e4f411..2488ba75 100644 --- a/src/core/view.h +++ b/src/core/view.h @@ -49,7 +49,6 @@ #ifndef RTORRENT_CORE_VIEW_DOWNLOADS_H #define RTORRENT_CORE_VIEW_DOWNLOADS_H -#include #include #include #include diff --git a/src/display/canvas.h b/src/display/canvas.h index 4fe3e43e..7023cada 100644 --- a/src/display/canvas.h +++ b/src/display/canvas.h @@ -62,10 +62,10 @@ public: static void resize_term(int x, int y) { resizeterm(y, x); } static void resize_term(std::pair dim) { resizeterm(dim.second, dim.first); } - unsigned int get_x() { int x, y; getyx(m_window, y, x); return x; } + unsigned int get_x() { int x, __UNUSED y; getyx(m_window, y, x); return x; } unsigned int get_y() { int x, y; getyx(m_window, y, x); return y; } - unsigned int width() { int x, y; getmaxyx(m_window, y, x); return x; } + unsigned int width() { int x, __UNUSED y; getmaxyx(m_window, y, x); return x; } unsigned int height() { int x, y; getmaxyx(m_window, y, x); return y; } void move(unsigned int x, unsigned int y) { wmove(m_window, y, x); } @@ -101,7 +101,7 @@ public: static void initialize(); static void cleanup(); - static int get_screen_width() { int x, y; getmaxyx(stdscr, y, x); return x; } + static int get_screen_width() { int x, __UNUSED y; getmaxyx(stdscr, y, x); return x; } static int get_screen_height() { int x, y; getmaxyx(stdscr, y, x); return y; } static std::pair term_size(); diff --git a/src/display/manager.cc b/src/display/manager.cc index 4bf34aa9..dde6a615 100644 --- a/src/display/manager.cc +++ b/src/display/manager.cc @@ -50,7 +50,7 @@ namespace display { Manager::Manager() : m_forceRedraw(false) { - m_taskUpdate.set_slot(rak::mem_fn(this, &Manager::receive_update)); + m_taskUpdate.slot() = std::tr1::bind(&Manager::receive_update, this); } Manager::~Manager() { diff --git a/src/display/text_element_value.cc b/src/display/text_element_value.cc index fe2d4674..bee86a49 100644 --- a/src/display/text_element_value.cc +++ b/src/display/text_element_value.cc @@ -112,7 +112,7 @@ TextElementValueBase::print(char* first, char* last, Canvas::attributes_list* at if (u == NULL) return first; - first += std::min(std::max(snprintf(first, last - first + 1, "%02u/%02u/%04u", u->tm_mday, (u->tm_mon + 1), (1900 + u->tm_year)), 0), last - first + 1);; + first += std::min(std::max(snprintf(first, last - first + 1, "%02u/%02u/%04u", u->tm_mday, (u->tm_mon + 1), (1900 + u->tm_year)), 0), last - first + 1); } else if (m_flags & flag_time) { time_t t = val; diff --git a/src/display/utils.cc b/src/display/utils.cc index b67ce632..2ab4c1a7 100644 --- a/src/display/utils.cc +++ b/src/display/utils.cc @@ -195,10 +195,10 @@ print_download_status(char* first, char* last, core::Download* d) { first = print_buffer(first, last, "Checking hash [%2i%%]", (d->download()->chunks_hashed() * 100) / d->download()->file_list()->size_chunks()); - } else if (d->tracker_list()->has_active()) { + } else if (d->tracker_list()->has_active_not_scrape()) { torrent::TrackerList::iterator itr = std::find_if(d->tracker_list()->begin(), d->tracker_list()->end(), - std::mem_fun(&torrent::Tracker::is_busy)); + std::mem_fun(&torrent::Tracker::is_busy_not_scrape)); char status[128]; (*itr)->get_status(status, sizeof(status)); diff --git a/src/display/window.cc b/src/display/window.cc index af433f6f..1246a681 100644 --- a/src/display/window.cc +++ b/src/display/window.cc @@ -59,7 +59,7 @@ Window::Window(Canvas* canvas, int flags, extent_type minWidth, extent_type minH m_maxWidth(maxWidth), m_maxHeight(maxHeight) { - m_taskUpdate.set_slot(rak::mem_fn(this, &Window::redraw)); + m_taskUpdate.slot() = std::tr1::bind(&Window::redraw, this); } Window::~Window() { diff --git a/src/display/window_download_list.cc b/src/display/window_download_list.cc index 614b93d8..0b407138 100644 --- a/src/display/window_download_list.cc +++ b/src/display/window_download_list.cc @@ -93,16 +93,15 @@ WindowDownloadList::redraw() { while (range.first != range.second) { char buffer[m_canvas->width() + 1]; - char* position; char* last = buffer + m_canvas->width() - 2 + 1; - position = print_download_title(buffer, last, *range.first); + print_download_title(buffer, last, *range.first); m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer); - position = print_download_info(buffer, last, *range.first); + print_download_info(buffer, last, *range.first); m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer); - position = print_download_status(buffer, last, *range.first); + print_download_status(buffer, last, *range.first); m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer); ++range.first; diff --git a/src/display/window_download_statusbar.cc b/src/display/window_download_statusbar.cc index 92905988..9c3deaab 100644 --- a/src/display/window_download_statusbar.cc +++ b/src/display/window_download_statusbar.cc @@ -63,33 +63,31 @@ WindowDownloadStatusbar::redraw() { m_canvas->erase(); char buffer[m_canvas->width()]; - char* position; char* last = buffer + m_canvas->width() - 2; - position = print_download_info(buffer, last, m_download); + print_download_info(buffer, last, m_download); m_canvas->print(0, 0, "%s", buffer); - position = buffer + std::min(std::max(snprintf(buffer, last - buffer, "Peers: %i(%i) Min/Max: %i/%i Slots: U:%i/%i D:%i/%i U/I/C/A: %i/%i/%i/%i Unchoked: %u/%u Failed: %i", - (int)m_download->download()->connection_list()->size(), - (int)m_download->download()->peer_list()->available_list_size(), - (int)m_download->download()->connection_list()->min_size(), - (int)m_download->download()->connection_list()->max_size(), - (int)m_download->download()->uploads_min(), - (int)m_download->download()->uploads_max(), - (int)m_download->download()->downloads_min(), - (int)m_download->download()->downloads_max(), - (int)m_download->download()->peers_currently_unchoked(), - (int)m_download->download()->peers_currently_interested(), - (int)m_download->download()->peers_complete(), - (int)m_download->download()->peers_accounted(), - (int)m_download->info()->upload_unchoked(), - (int)m_download->info()->download_unchoked(), - (int)m_download->chunks_failed()), - 0), last - buffer); + snprintf(buffer, last - buffer, "Peers: %i(%i) Min/Max: %i/%i Slots: U:%i/%i D:%i/%i U/I/C/A: %i/%i/%i/%i Unchoked: %u/%u Failed: %i", + (int)m_download->download()->connection_list()->size(), + (int)m_download->download()->peer_list()->available_list_size(), + (int)m_download->download()->connection_list()->min_size(), + (int)m_download->download()->connection_list()->max_size(), + (int)m_download->download()->uploads_min(), + (int)m_download->download()->uploads_max(), + (int)m_download->download()->downloads_min(), + (int)m_download->download()->downloads_max(), + (int)m_download->download()->peers_currently_unchoked(), + (int)m_download->download()->peers_currently_interested(), + (int)m_download->download()->peers_complete(), + (int)m_download->download()->peers_accounted(), + (int)m_download->info()->upload_unchoked(), + (int)m_download->info()->download_unchoked(), + (int)m_download->chunks_failed()); m_canvas->print(0, 1, "%s", buffer); - position = print_download_status(buffer, last, m_download); + print_download_status(buffer, last, m_download); m_canvas->print(0, 2, "[%c:%i] %s", m_download->tracker_list()->has_active() ? 'C' : ' ', (int)(m_download->download()->tracker_controller()->seconds_to_next_timeout()), diff --git a/src/display/window_file_list.cc b/src/display/window_file_list.cc index 6a923dc7..7c9f692e 100644 --- a/src/display/window_file_list.cc +++ b/src/display/window_file_list.cc @@ -123,7 +123,7 @@ WindowFileList::redraw() { if (fl->size_files() == 0 || m_canvas->height() < 2) return; - iterator entries[m_canvas->height() - 1]; + std::vector entries(m_canvas->height() - 1); unsigned int last = 0; diff --git a/src/display/window_log.cc b/src/display/window_log.cc index 03936833..3b36dbe3 100644 --- a/src/display/window_log.cc +++ b/src/display/window_log.cc @@ -48,7 +48,7 @@ WindowLog::WindowLog(core::Log* l) : Window(new Canvas, 0, 0, 0, extent_full, extent_static), m_log(l) { - m_taskUpdate.set_slot(rak::mem_fn(this, &WindowLog::receive_update)), + m_taskUpdate.slot() = std::tr1::bind(&WindowLog::receive_update, this); // We're trying out scheduled tasks instead. m_connUpdate = l->signal_update().connect(sigc::mem_fun(*this, &WindowLog::receive_update)); diff --git a/src/display/window_tracker_list.cc b/src/display/window_tracker_list.cc index ac2d78dc..3dcee109 100644 --- a/src/display/window_tracker_list.cc +++ b/src/display/window_tracker_list.cc @@ -83,11 +83,6 @@ WindowTrackerList::redraw() { while (range.first != range.second) { torrent::Tracker* tracker = tl->at(range.first); -// m_canvas->print(0, pos, "[%c] [S/L %5i/%5i] %s", -// tracker->is_enabled() ? (tracker->is_open() ? '*' : ' ') : '-', -// tracker->scrape_complete(), tracker->scrape_incomplete(), -// tracker->url().c_str()); - if (tracker->group() == group) m_canvas->print(0, pos, "%2i:", group++); @@ -95,30 +90,27 @@ WindowTrackerList::redraw() { tracker->url().c_str()); if (pos < m_canvas->height()) - m_canvas->print(4, pos++, "Id: %s Counters: %uf / %us (%u) %s %s S/L/D: %u/%u/%u (%u/%u)", + m_canvas->print(0, pos++, "%s Id: %s Counters: %uf / %us (%u) %s S/L/D: %u/%u/%u (%u/%u)", + tracker->is_busy() ? "req " : " ", rak::copy_escape_html(tracker->tracker_id()).c_str(), tracker->failed_counter(), tracker->success_counter(), tracker->scrape_counter(), tracker->is_usable() ? " on" : tracker->is_enabled() ? "err" : "off", - tracker->is_busy() ? "req" : " ", tracker->scrape_complete(), tracker->scrape_incomplete(), tracker->scrape_downloaded(), tracker->latest_new_peers(), tracker->latest_sum_peers()); -// m_canvas->print(4, pos++, "Id: %s Focus: %s Enabled: %s Open: %s Timer: %u/%u", -// rak::copy_escape_html(tracker->tracker_id()).c_str(), -// range.first == tl->focus() ? "yes" : " no", -// tracker->is_enabled() ? "yes" : " no", -// tracker->is_open() ? "yes" : " no", -// tracker->normal_interval(), -// tracker->min_interval()); - if (range.first == *m_focus) { - m_canvas->set_attr(0, pos - 2, m_canvas->width(), is_focused() ? A_REVERSE : A_BOLD, COLOR_PAIR(0)); - m_canvas->set_attr(0, pos - 1, m_canvas->width(), is_focused() ? A_REVERSE : A_BOLD, COLOR_PAIR(0)); + m_canvas->set_attr(4, pos - 2, m_canvas->width(), is_focused() ? A_REVERSE : A_BOLD, COLOR_PAIR(0)); + m_canvas->set_attr(4, pos - 1, m_canvas->width(), is_focused() ? A_REVERSE : A_BOLD, COLOR_PAIR(0)); + } + + if (tracker->is_busy()) { + m_canvas->set_attr(0, pos - 2, 4, A_REVERSE, COLOR_PAIR(0)); + m_canvas->set_attr(0, pos - 1, 4, A_REVERSE, COLOR_PAIR(0)); } range.first++; diff --git a/src/main.cc b/src/main.cc index 43474d6e..435c70e1 100644 --- a/src/main.cc +++ b/src/main.cc @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -79,8 +80,6 @@ #include "thread_main.h" #include "thread_worker.h" -namespace std { using namespace tr1; } - void handle_sigbus(int signum, siginfo_t* sa, void* ptr); void do_panic(int signum); void print_help(); @@ -195,6 +194,7 @@ main(int argc, char** argv) { // to process new non-socket events. 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()); // Initialize option handlers after libtorrent to ensure @@ -636,18 +636,6 @@ main(int argc, char** argv) { CMD2_REDIRECT ("get_session_on_completion", "session.on_completion"); CMD2_REDIRECT_GENERIC("set_session_on_completion", "session.on_completion.set"); - CMD2_REDIRECT ("hash_read_ahead", "system.hash.read_ahead.set"); - CMD2_REDIRECT ("get_hash_read_ahead", "system.hash.read_ahead"); - CMD2_REDIRECT_GENERIC("set_hash_read_ahead", "system.hash.read_ahead.set"); - - CMD2_REDIRECT ("hash_interval", "system.hash.interval.set"); - CMD2_REDIRECT ("get_hash_interval", "system.hash.interval"); - CMD2_REDIRECT_GENERIC("set_hash_interval", "system.hash.interval.set"); - - CMD2_REDIRECT ("hash_max_tries", "system.hash.max_tries.set"); - CMD2_REDIRECT ("get_hash_max_tries", "system.hash.max_tries"); - CMD2_REDIRECT_GENERIC("set_hash_max_tries", "system.hash.max_tries.set"); - CMD2_REDIRECT ("check_hash", "pieces.hash.on_completion.set"); CMD2_REDIRECT ("get_check_hash", "pieces.hash.on_completion"); CMD2_REDIRECT_GENERIC("set_check_hash", "pieces.hash.on_completion.set"); @@ -878,7 +866,7 @@ main(int argc, char** argv) { rak::priority_queue_perform(&taskScheduler, cachedTime); // Do shutdown check before poll, not after. - main_thread->poll_manager()->poll(client_next_timeout(control)); + main_thread->poll()->do_poll(client_next_timeout(control).usec()); } control->core()->download_list()->session_save(); diff --git a/src/rpc/command.h b/src/rpc/command.h index bbb6ccdb..db4b2eaf 100644 --- a/src/rpc/command.h +++ b/src/rpc/command.h @@ -47,9 +47,7 @@ #include // Move into config.h or something. -namespace std { - using namespace tr1; -} +namespace tr1 { using namespace std::tr1; } namespace core { class Download; @@ -113,7 +111,7 @@ typedef rt_triple target_type; class command_base; typedef const torrent::Object (*command_base_call_type)(command_base*, target_type, const torrent::Object&); -typedef std::function base_function; +typedef tr1::function base_function; template struct command_base_is_valid {}; template struct command_base_is_type {}; @@ -210,9 +208,16 @@ protected: // within commands. E.d. callable command strings where one of the // arguments within the command needs to be supplied by the caller. +#ifdef HAVE_CXX11 + union { + base_function t_pod; + // char t_pod[sizeof(base_function)]; + }; +#else union { char t_pod[sizeof(base_function)]; }; +#endif }; template @@ -245,7 +250,7 @@ command_base::_call(command_base* cmd, target_type target, Args args) { } #define COMMAND_BASE_TEMPLATE_TYPE(func_type, func_parm) \ - template ::proper_type> struct func_type { typedef std::function type; }; \ + template ::proper_type> struct func_type { typedef tr1::function type; }; \ \ template <> struct command_base_is_valid::type> { static const int value = 1; }; \ template <> struct command_base_is_valid::type> { static const int value = 1; }; \ diff --git a/src/rpc/command_scheduler.cc b/src/rpc/command_scheduler.cc index 97e0cae8..4968e8da 100644 --- a/src/rpc/command_scheduler.cc +++ b/src/rpc/command_scheduler.cc @@ -71,7 +71,7 @@ CommandScheduler::insert(const std::string& key) { delete *itr; *itr = new CommandSchedulerItem(key); - (*itr)->set_slot(rak::bind_mem_fn(this, &CommandScheduler::call_item, *itr)); + (*itr)->slot() = std::tr1::bind(&CommandScheduler::call_item, this, *itr); return itr; } diff --git a/src/rpc/command_scheduler_item.h b/src/rpc/command_scheduler_item.h index 4556d249..e897d314 100644 --- a/src/rpc/command_scheduler_item.h +++ b/src/rpc/command_scheduler_item.h @@ -39,33 +39,34 @@ #include "globals.h" +#include #include namespace rpc { class CommandSchedulerItem { public: - typedef rak::function0 Slot; + typedef std::tr1::function slot_void; CommandSchedulerItem(const std::string& key) : m_key(key), m_interval(0) {} ~CommandSchedulerItem(); - bool is_queued() const { return m_task.is_queued(); } + bool is_queued() const { return m_task.is_queued(); } void enable(rak::timer t); void disable(); - const std::string& key() const { return m_key; } - torrent::Object& command() { return m_command; } + const std::string& key() const { return m_key; } + torrent::Object& command() { return m_command; } // 'interval()' should in the future return some more dynamic values. - uint32_t interval() const { return m_interval; } - void set_interval(uint32_t v) { m_interval = v; } + uint32_t interval() const { return m_interval; } + void set_interval(uint32_t v) { m_interval = v; } - rak::timer time_scheduled() const { return m_timeScheduled; } + rak::timer time_scheduled() const { return m_timeScheduled; } rak::timer next_time_scheduled() const; - void set_slot(Slot::base_type* s) { m_task.set_slot(s); } + slot_void& slot() { return m_task.slot(); } private: CommandSchedulerItem(const CommandSchedulerItem&); diff --git a/src/rpc/fixed_key.h b/src/rpc/fixed_key.h index 91b29d5a..4261ab2c 100644 --- a/src/rpc/fixed_key.h +++ b/src/rpc/fixed_key.h @@ -63,7 +63,7 @@ public: static fixed_key_type from_string(const std::string& str) { fixed_key_type k; k.set_c_str(str.c_str(), str.size()); return k; } static fixed_key_type from_raw_string(const torrent::raw_string& str) { fixed_key_type k; k.set_data(str.data(), str.size()); return k; } - bool empty() const { return m_size == 0;; } + bool empty() const { return m_size == 0; } size_type size() const { return m_size; } iterator begin() const { return m_data; } diff --git a/src/rpc/object_storage.cc b/src/rpc/object_storage.cc index 8d8a021c..9a7bfa1c 100644 --- a/src/rpc/object_storage.cc +++ b/src/rpc/object_storage.cc @@ -246,7 +246,7 @@ object_storage::rlookup_list(const std::string& cmd_key) { if (r_itr != m_rlookup.end()) std::transform(r_itr->second.begin(), r_itr->second.end(), std::back_inserter(result), - std::bind(&key_type::c_str, std::bind(rak::mem_ptr(&value_type::first), std::placeholders::_1))); + std::tr1::bind(&key_type::c_str, std::tr1::bind(rak::mem_ptr(&value_type::first), std::tr1::placeholders::_1))); return result; } diff --git a/src/rpc/object_storage.h b/src/rpc/object_storage.h index 41a8e0f9..39bf0dbf 100644 --- a/src/rpc/object_storage.h +++ b/src/rpc/object_storage.h @@ -56,7 +56,7 @@ struct object_storage_node { char flags; }; -typedef std::unordered_map, object_storage_node, hash_fixed_key_type> object_storage_base_type; +typedef std::tr1::unordered_map, object_storage_node, hash_fixed_key_type> object_storage_base_type; class object_storage : private object_storage_base_type { public: diff --git a/src/rpc/xmlrpc.cc b/src/rpc/xmlrpc.cc index 261259de..8bacd882 100644 --- a/src/rpc/xmlrpc.cc +++ b/src/rpc/xmlrpc.cc @@ -156,7 +156,7 @@ xmlrpc_to_target(xmlrpc_env* env, xmlrpc_value* value) { throw xmlrpc_error(XMLRPC_TYPE_ERROR, "Unsupported target type found."); } - core::Download* download = xmlrpc.get_slot_find_download()(str); + core::Download* download = xmlrpc.slot_find_download()(str); if (download == NULL) { ::free((void*)str); @@ -186,7 +186,7 @@ xmlrpc_to_target(xmlrpc_env* env, xmlrpc_value* value) { if (*str == '\0' || *end_ptr != '\0') throw xmlrpc_error(XMLRPC_TYPE_ERROR, "Invalid index."); - target = rpc::make_target(XmlRpc::call_file, xmlrpc.get_slot_find_file()(download, index)); + target = rpc::make_target(XmlRpc::call_file, xmlrpc.slot_find_file()(download, index)); break; case 't': @@ -195,7 +195,7 @@ xmlrpc_to_target(xmlrpc_env* env, xmlrpc_value* value) { if (*str == '\0' || *end_ptr != '\0') throw xmlrpc_error(XMLRPC_TYPE_ERROR, "Invalid index."); - target = rpc::make_target(XmlRpc::call_tracker, xmlrpc.get_slot_find_tracker()(download, index)); + target = rpc::make_target(XmlRpc::call_tracker, xmlrpc.slot_find_tracker()(download, index)); break; case 'p': @@ -206,7 +206,7 @@ xmlrpc_to_target(xmlrpc_env* env, xmlrpc_value* value) { if (hash_end == end_ptr || *hash_end != '\0') throw xmlrpc_error(XMLRPC_TYPE_ERROR, "Not a hash string."); - target = rpc::make_target(XmlRpc::call_peer, xmlrpc.get_slot_find_peer()(download, hash)); + target = rpc::make_target(XmlRpc::call_peer, xmlrpc.slot_find_peer()(download, hash)); break; } default: @@ -233,8 +233,8 @@ xmlrpc_to_index_type(int index, int callType, core::Download* download) { void* result; switch (callType) { - case XmlRpc::call_file: result = xmlrpc.get_slot_find_file()(download, index); break; - case XmlRpc::call_tracker: result = xmlrpc.get_slot_find_tracker()(download, index); break; + case XmlRpc::call_file: result = xmlrpc.slot_find_file()(download, index); break; + case XmlRpc::call_tracker: result = xmlrpc.slot_find_tracker()(download, index); break; default: result = NULL; break; } diff --git a/src/rpc/xmlrpc.h b/src/rpc/xmlrpc.h index be909ec9..34422014 100644 --- a/src/rpc/xmlrpc.h +++ b/src/rpc/xmlrpc.h @@ -37,7 +37,7 @@ #ifndef RTORRENT_RPC_XMLRPC_H #define RTORRENT_RPC_XMLRPC_H -#include +#include #include namespace core { @@ -54,11 +54,11 @@ namespace rpc { class XmlRpc { public: - typedef rak::function1 slot_find_download; - typedef rak::function2 slot_find_file; - typedef rak::function2 slot_find_tracker; - typedef rak::function2 slot_find_peer; - typedef rak::function2 slot_write; + typedef std::tr1::function slot_download; + typedef std::tr1::function slot_file; + typedef std::tr1::function slot_tracker; + typedef std::tr1::function slot_peer; + typedef std::tr1::function slot_write; static const int dialect_generic = 0; static const int dialect_i8 = 1; @@ -87,17 +87,10 @@ public: int dialect() { return m_dialect; } void set_dialect(int dialect); - slot_find_download& get_slot_find_download() { return m_slotFindDownload; } - void set_slot_find_download(slot_find_download::base_type* slot) { m_slotFindDownload.set(slot); } - - slot_find_file& get_slot_find_file() { return m_slotFindFile; } - void set_slot_find_file(slot_find_file::base_type* slot) { m_slotFindFile.set(slot); } - - slot_find_tracker& get_slot_find_tracker() { return m_slotFindTracker; } - void set_slot_find_tracker(slot_find_tracker::base_type* slot) { m_slotFindTracker.set(slot); } - - slot_find_peer& get_slot_find_peer() { return m_slotFindPeer; } - void set_slot_find_peer(slot_find_peer::base_type* slot) { m_slotFindPeer.set(slot); } + slot_download& slot_find_download() { return m_slotFindDownload; } + slot_file& slot_find_file() { return m_slotFindFile; } + slot_tracker& slot_find_tracker() { return m_slotFindTracker; } + slot_peer& slot_find_peer() { return m_slotFindPeer; } static int64_t size_limit(); static void set_size_limit(uint64_t size); @@ -108,10 +101,10 @@ private: int m_dialect; - slot_find_download m_slotFindDownload; - slot_find_file m_slotFindFile; - slot_find_tracker m_slotFindTracker; - slot_find_peer m_slotFindPeer; + slot_download m_slotFindDownload; + slot_file m_slotFindFile; + slot_tracker m_slotFindTracker; + slot_peer m_slotFindPeer; }; } diff --git a/src/thread_base.cc b/src/thread_base.cc index 936f382c..0640cac6 100644 --- a/src/thread_base.cc +++ b/src/thread_base.cc @@ -82,7 +82,7 @@ public: throw torrent::internal_error("Overflowed thread_queue."); __sync_bool_compare_and_swap(itr, NULL, v); - __sync_bool_compare_and_swap(&m_lock, 1, 0); + unlock(); } value_type* copy_and_clear(value_type* dest) { @@ -107,78 +107,31 @@ public: void throw_shutdown_exception() { throw torrent::shutdown_exception(); } -ThreadBase::ThreadBase() : - m_state(STATE_UNKNOWN), - m_pollManager(NULL) { - // Init the poll manager in a special init function called by the - // thread itself. Need to be careful with what external stuff - // create_poll_manager calls in that case. - std::memset(&m_thread, 0, sizeof(pthread_t)); - - m_taskShutdown.set_slot(rak::ptr_fn(&throw_shutdown_exception)); +ThreadBase::ThreadBase() { + m_taskShutdown.slot() = std::tr1::bind(&throw_shutdown_exception); m_threadQueue = new thread_queue_hack; } ThreadBase::~ThreadBase() { - delete m_pollManager; delete m_threadQueue; } -void -ThreadBase::start_thread() { - if (m_state != STATE_INITIALIZED || - pthread_create(&m_thread, NULL, (pthread_func)&ThreadBase::event_loop, this)) - throw torrent::internal_error("Failed to create thread."); -} - +// Move to libtorrent... void ThreadBase::stop_thread(ThreadBase* thread) { if (!thread->m_taskShutdown.is_queued()) priority_queue_insert(&thread->m_taskScheduler, &thread->m_taskShutdown, cachedTime); } -inline rak::timer -ThreadBase::client_next_timeout() { +int64_t +ThreadBase::next_timeout_usec() { if (m_taskScheduler.empty()) - return rak::timer::from_seconds(600); + return rak::timer::from_seconds(600).usec(); else if (m_taskScheduler.top()->time() <= cachedTime) return 0; else - return m_taskScheduler.top()->time() - cachedTime; -} - -void* -ThreadBase::event_loop(ThreadBase* threadBase) { - // Setup stuff... - threadBase->m_state = STATE_ACTIVE; - - // Set local poll and priority queue. - - try { - - while (true) { - // Check for new queued items set by other threads. - if (!threadBase->m_threadQueue->empty()) - threadBase->call_queued_items(); - - // // Remember to add global lock thing to the main poll loop ++. - - rak::priority_queue_perform(&threadBase->m_taskScheduler, cachedTime); - - threadBase->m_pollManager->poll_simple(threadBase->client_next_timeout()); - } - - } catch (torrent::shutdown_exception& e) { - acquire_global_lock(); - lt_log_print(torrent::LOG_THREAD_NOTICE, "Shutting down thread."); - release_global_lock(); - } - - threadBase->m_state = STATE_INACTIVE; - __sync_synchronize(); - - return NULL; + return (m_taskScheduler.top()->time() - cachedTime).usec(); } void @@ -191,6 +144,15 @@ ThreadBase::call_queued_items() { (*first++)(this); } +void +ThreadBase::call_events() { + // Check for new queued items set by other threads. + if (!m_threadQueue->empty()) + call_queued_items(); + + rak::priority_queue_perform(&m_taskScheduler, cachedTime); +} + void ThreadBase::queue_item(thread_base_func newFunc) { m_threadQueue->push_back(newFunc); diff --git a/src/thread_base.h b/src/thread_base.h index 8b4013c2..479e3cdd 100644 --- a/src/thread_base.h +++ b/src/thread_base.h @@ -39,42 +39,26 @@ #include #include -#include +#include #include "rak/priority_queue_default.h" #include "core/poll_manager.h" -struct thread_queue_hack; - // Move this class to libtorrent. -struct thread_queue_hack; +class thread_queue_hack; -class ThreadBase : public torrent::ThreadBase { +class ThreadBase : public torrent::thread_base { public: typedef rak::priority_queue_default priority_queue; typedef void (*thread_base_func)(ThreadBase*); - typedef void* (*pthread_func)(void*); - - enum state_type { - STATE_UNKNOWN, - STATE_INITIALIZED, - STATE_ACTIVE, - STATE_INACTIVE - }; ThreadBase(); virtual ~ThreadBase(); - bool is_active() const { return m_state == STATE_ACTIVE; } - - torrent::Poll* poll() { return m_pollManager->get_torrent_poll(); } - core::PollManager* poll_manager() { return m_pollManager; } priority_queue& task_scheduler() { return m_taskScheduler; } - virtual void init_thread() = 0; - - void start_thread(); + // Throw torrent::shutdown_exception to stop the thread. static void stop_thread(ThreadBase* thread); // ATM, only interaction with a thread's allowed by other threads is @@ -82,8 +66,6 @@ public: void queue_item(thread_base_func newFunc); - static void* event_loop(ThreadBase* threadBase); - // Only call this when global lock has been acquired, as it checks // ThreadBase::is_main_polling() which is only guaranteed to remain // 'false' if global lock keeps main thread from entering polling @@ -93,18 +75,15 @@ public: static void interrupt_main_polling(); protected: - inline rak::timer client_next_timeout(); + int64_t next_timeout_usec(); void call_queued_items(); + virtual void call_events(); // TODO: Add thread name. - pthread_t m_thread; - state_type m_state; - // The timer needs to be sync'ed when updated... - core::PollManager* m_pollManager; rak::priority_queue_default m_taskScheduler; rak::priority_item m_taskShutdown; diff --git a/src/thread_main.cc b/src/thread_main.cc index b87cae52..09c78989 100644 --- a/src/thread_main.cc +++ b/src/thread_main.cc @@ -40,6 +40,7 @@ #include "globals.h" #include +#include ThreadMain::~ThreadMain() { } @@ -49,8 +50,8 @@ ThreadMain::init_thread() { // The main thread always holds the lock while running. acquire_global_lock(); - m_pollManager = core::PollManager::create_poll_manager(); - m_pollManager->get_torrent_poll()->set_flags(torrent::Poll::flag_waive_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_worker.cc b/src/thread_worker.cc index cdfe3323..79cd49ea 100644 --- a/src/thread_worker.cc +++ b/src/thread_worker.cc @@ -52,7 +52,7 @@ #include "rpc/parse_commands.h" ThreadWorker::ThreadWorker() { - m_taskTouchLog.set_slot(rak::mem_fn(this, &ThreadWorker::task_touch_log)); + m_taskTouchLog.slot() = std::tr1::bind(&ThreadWorker::task_touch_log, this); } ThreadWorker::~ThreadWorker() { @@ -62,8 +62,7 @@ ThreadWorker::~ThreadWorker() { void ThreadWorker::init_thread() { - m_pollManager = core::PollManager::create_poll_manager(); - + m_poll = core::create_poll(); m_state = STATE_INITIALIZED; } diff --git a/test/rpc/command_map_test.cc b/test/rpc/command_map_test.cc index 08022fcd..95fd44e7 100644 --- a/test/rpc/command_map_test.cc +++ b/test/rpc/command_map_test.cc @@ -3,7 +3,7 @@ #include "command_helpers.h" #include "rpc/command_map.h" -#import "command_map_test.h" +#include "command_map_test.h" CPPUNIT_TEST_SUITE_REGISTRATION(CommandMapTest); diff --git a/test/rpc/command_slot_test.cc b/test/rpc/command_slot_test.cc index c968644e..f2e992cc 100644 --- a/test/rpc/command_slot_test.cc +++ b/test/rpc/command_slot_test.cc @@ -4,7 +4,7 @@ #include #include "rpc/command_map.h" -#import "command_slot_test.h" +#include "command_slot_test.h" CPPUNIT_TEST_SUITE_REGISTRATION(CommandSlotTest); @@ -25,7 +25,7 @@ CommandSlotTest::test_basics() { // test_any.set_function(&cmd_test_a); // CPPUNIT_ASSERT(rpc::command_base_call_any(&test_any, rpc::make_target(), (int64_t)1).as_value() == 1); -// test_any.set_function(std::bind(&cmd_test_b, std::placeholders::_1, std::placeholders::_2, (uint64_t)2)); +// test_any.set_function(tr1::bind(&cmd_test_b, tr1::placeholders::_1, tr1::placeholders::_2, (uint64_t)2)); // CPPUNIT_ASSERT(rpc::command_base_call_any(&test_any, rpc::make_target(), (int64_t)1).as_value() == 2); // test_any.set_function(&cmd_test_list); diff --git a/test/rpc/command_test.cc b/test/rpc/command_test.cc index 4d9348ab..274333d5 100644 --- a/test/rpc/command_test.cc +++ b/test/rpc/command_test.cc @@ -1,6 +1,6 @@ #include "config.h" -#import "command_test.h" +#include "command_test.h" CPPUNIT_TEST_SUITE_REGISTRATION(CommandTest); diff --git a/test/rpc/object_storage_test.cc b/test/rpc/object_storage_test.cc index fedac927..cf580404 100644 --- a/test/rpc/object_storage_test.cc +++ b/test/rpc/object_storage_test.cc @@ -1,6 +1,6 @@ #include "config.h" -#import "object_storage_test.h" +#include "object_storage_test.h" CPPUNIT_TEST_SUITE_REGISTRATION(ObjectStorageTest); diff --git a/test/src/command_dynamic_test.cc b/test/src/command_dynamic_test.cc index 675120f4..377141ef 100644 --- a/test/src/command_dynamic_test.cc +++ b/test/src/command_dynamic_test.cc @@ -2,7 +2,7 @@ #include -#import "command_dynamic_test.h" +#include "command_dynamic_test.h" #include "rpc/parse_commands.h" #include "control.h"