diff --git a/libtorrent/include/libtorrent/bandwidth_manager.hpp b/libtorrent/include/libtorrent/bandwidth_manager.hpp index 83df5b371..ef132543f 100644 --- a/libtorrent/include/libtorrent/bandwidth_manager.hpp +++ b/libtorrent/include/libtorrent/bandwidth_manager.hpp @@ -181,6 +181,7 @@ struct bandwidth_manager , m_current_quota(0) , m_channel(channel) , m_in_hand_out_bandwidth(false) + , m_abort(false) {} void throttle(int limit) throw() @@ -196,6 +197,12 @@ struct bandwidth_manager return m_limit; } + void close() + { + m_abort = true; + m_history_timer.cancel(); + } + // non prioritized means that, if there's a line for bandwidth, // others will cut in front of the non-prioritized peers. // this is used by web seeds @@ -275,6 +282,8 @@ private: // active that will be invoked, no need to set one up if (m_history.size() > 1) return; + if (m_abort) return; + m_history_timer.expires_at(e.expires_at); m_history_timer.async_wait(bind(&bandwidth_manager::on_history_expire, this, _1)); #ifndef NDEBUG @@ -308,7 +317,7 @@ private: } // now, wait for the next chunk to expire - if (!m_history.empty()) + if (!m_history.empty() && !m_abort) { m_history_timer.expires_at(m_history.back().expires_at); m_history_timer.async_wait(bind(&bandwidth_manager::on_history_expire, this, _1)); @@ -487,6 +496,7 @@ private: // to prevent recursive invocations to interfere bool m_in_hand_out_bandwidth; + bool m_abort; }; } diff --git a/libtorrent/include/libtorrent/torrent.hpp b/libtorrent/include/libtorrent/torrent.hpp index 99bbefb82..5ee5ddb03 100755 --- a/libtorrent/include/libtorrent/torrent.hpp +++ b/libtorrent/include/libtorrent/torrent.hpp @@ -128,6 +128,8 @@ namespace libtorrent #ifndef TORRENT_DISABLE_EXTENSIONS void add_extension(boost::shared_ptr); + void add_extension(boost::function(torrent*, void*)> const& ext + , void* userdata); #endif // this is called when the torrent has metadata. diff --git a/libtorrent/include/libtorrent/torrent_handle.hpp b/libtorrent/include/libtorrent/torrent_handle.hpp index 8ae2f7f41..7ddb218a6 100755 --- a/libtorrent/include/libtorrent/torrent_handle.hpp +++ b/libtorrent/include/libtorrent/torrent_handle.hpp @@ -64,6 +64,8 @@ namespace libtorrent struct checker_impl; } + struct torrent_plugin; + struct TORRENT_EXPORT duplicate_torrent: std::exception { virtual const char* what() const throw() @@ -279,6 +281,11 @@ namespace libtorrent void remove_url_seed(std::string const& url) const; std::set url_seeds() const; +#ifndef TORRENT_DISABLE_EXTENSIONS + void add_extension(boost::function(torrent*, void*)> const& ext + , void* userdata = 0); +#endif + bool has_metadata() const; const torrent_info& get_torrent_info() const; bool is_valid() const; diff --git a/libtorrent/src/session_impl.cpp b/libtorrent/src/session_impl.cpp index 9f7255b7f..b3eba0bf7 100755 --- a/libtorrent/src/session_impl.cpp +++ b/libtorrent/src/session_impl.cpp @@ -753,6 +753,9 @@ namespace detail #endif m_half_open.close(); + m_download_channel.close(); + m_upload_channel.close(); + mutex::scoped_lock l2(m_checker_impl.m_mutex); // abort the checker thread m_checker_impl.m_abort = true; diff --git a/libtorrent/src/torrent.cpp b/libtorrent/src/torrent.cpp index c38111908..84f30aa2d 100755 --- a/libtorrent/src/torrent.cpp +++ b/libtorrent/src/torrent.cpp @@ -346,10 +346,34 @@ namespace libtorrent } #ifndef TORRENT_DISABLE_EXTENSIONS + void torrent::add_extension(boost::shared_ptr ext) { m_extensions.push_back(ext); } + + void torrent::add_extension(boost::function(torrent*, void*)> const& ext + , void* userdata) + { + boost::shared_ptr tp(ext(this, userdata)); + if (!tp) return; + + add_extension(tp); + + for (peer_iterator i = m_connections.begin(); + i != m_connections.end(); ++i) + { + peer_connection* p = *i; + boost::shared_ptr pp(tp->new_connection(p)); + if (pp) p->add_extension(pp); + } + + // if files are checked for this torrent, call the extension + // to let it initialize itself + if (m_connections_initialized) + tp->on_files_checked(); + } + #endif // this may not be called from a constructor because of the call to diff --git a/libtorrent/src/torrent_handle.cpp b/libtorrent/src/torrent_handle.cpp index dd6dd3c21..b19e05bb4 100755 --- a/libtorrent/src/torrent_handle.cpp +++ b/libtorrent/src/torrent_handle.cpp @@ -247,6 +247,20 @@ namespace libtorrent find_torrent(m_ses, m_chk, m_info_hash)->move_storage(save_path); } + void torrent_handle::add_extension( + boost::function(torrent*, void*)> const& ext + , void* userdata) + { + INVARIANT_CHECK; + + if (m_ses == 0) throw_invalid_handle(); + TORRENT_ASSERT(m_chk); + + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); + mutex::scoped_lock l2(m_chk->m_mutex); + return find_torrent(m_ses, m_chk, m_info_hash)->add_extension(ext, userdata); + } + bool torrent_handle::has_metadata() const { INVARIANT_CHECK; diff --git a/src/deluge_core.cpp b/src/deluge_core.cpp index dad042441..8109f694a 100644 --- a/src/deluge_core.cpp +++ b/src/deluge_core.cpp @@ -371,6 +371,7 @@ static PyObject *torrent_init(PyObject *self, PyObject *args) // Init values M_settings->user_agent = std::string(user_agent); + M_settings->stop_tracker_timeout = 3; M_settings->lazy_bitfields = 1; #if defined(_WIN32) DWORD windows_version = ::GetVersion(); @@ -428,9 +429,6 @@ static PyObject *torrent_init(PyObject *self, PyObject *args) static PyObject *torrent_quit(PyObject *self, PyObject *args) { - M_settings->stop_tracker_timeout = 3; - M_settings->tracker_receive_timeout = 3; - M_ses->set_settings(*M_settings); printf("core: removing torrents...\r\n"); delete M_torrents; printf("core: removing settings...\r\n"); diff --git a/src/interface.py b/src/interface.py index 97f4e6104..ec894a288 100644 --- a/src/interface.py +++ b/src/interface.py @@ -1637,13 +1637,13 @@ want to remove all seeding torrents?")): self.save_column_widths() self.save_window_settings() self.save_tabs_order() + gtk.main_quit() enabled_plugins = ':'.join(self.plugins.get_enabled_plugins()) self.config.set('enabled_plugins', enabled_plugins) self.config.save() self.plugins.shutdown_all_plugins() #for the sake of windows, hide tray_icon self.tray_icon.set_visible(False) - gtk.main_quit() self.manager.quit() ## For testing purposes, create a copy of the interface