diff --git a/docs/manual.rst b/docs/manual.rst index c96ba776b..2053ac089 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -2384,6 +2384,8 @@ Its declaration looks like this:: bool operator==(torrent_handle const&) const; bool operator!=(torrent_handle const&) const; bool operator<(torrent_handle const&) const; + + boost::shared_ptr native_handle() const; }; The default constructor will initialize the handle to an invalid state. Which @@ -2631,8 +2633,8 @@ this torrent. You must have completed the download of the specified piece before calling this function. When the read operation is completed, it is passed back through an alert, -read_piece_alert_. In order to receive this alert, you must enable -``alert::storage_notification`` in your alert mask (see `set_alert_mask()`_). +read_piece_alert_. Since this alert is a reponse to an explicit call, it will +always be posted, regardless of the alert mask. Note that if you read multiple pieces, the read operations are not guaranteed to finish in the same order as you initiated them. @@ -3377,6 +3379,20 @@ ssl certificate. If you receive a torrent_need_cert_alert_, you need to call this to provide a valid cert. If you don't have a cert you won't be allowed to connect to any peers. +native_handle() +--------------- + + :: + + boost::shared_ptr native_handle() const; + +This function is intended only for use by plugins and the alert dispatch function. Any code +that runs in libtorrent's network thread may not use the public API of ``torrent_handle``. +Doing so results in a dead-lock. For such routines, the ``native_handle`` gives access to the +underlying type representing the torrent. This type does not have a stable API and should +be relied on as little as possible. + + torrent_status ============== diff --git a/include/libtorrent/torrent_handle.hpp b/include/libtorrent/torrent_handle.hpp index b900318ef..73d0f4963 100644 --- a/include/libtorrent/torrent_handle.hpp +++ b/include/libtorrent/torrent_handle.hpp @@ -70,6 +70,7 @@ namespace libtorrent struct peer_info; struct peer_list_entry; struct torrent_status; + class torrent; TORRENT_EXPORT std::size_t hash_value(torrent_status const& ts); @@ -417,6 +418,8 @@ namespace libtorrent bool operator<(const torrent_handle& h) const { return m_torrent.lock() < h.m_torrent.lock(); } + boost::shared_ptr native_handle() const; + private: torrent_handle(boost::weak_ptr const& t) diff --git a/src/alert.cpp b/src/alert.cpp index ceea03dd5..271006398 100644 --- a/src/alert.cpp +++ b/src/alert.cpp @@ -411,6 +411,19 @@ namespace libtorrent { mutex::scoped_lock lock(m_mutex); post_impl(a); + +#ifndef TORRENT_DISABLE_EXTENSIONS + lock.unlock(); + + for (ses_extension_list_t::iterator i = m_ses_extensions.begin() + , end(m_ses_extensions.end()); i != end; ++i) + { + TORRENT_TRY { + (*i)->on_alert(alert_); + } TORRENT_CATCH(std::exception&) {} + } +#endif + } void alert_manager::post_alert(const alert& alert_) diff --git a/src/torrent.cpp b/src/torrent.cpp index 5769b9495..9c3c0ddde 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -1204,11 +1204,8 @@ namespace libtorrent size = 0; } - if (m_ses.m_alerts.should_post()) - { - m_ses.m_alerts.post_alert(read_piece_alert( - get_handle(), r.piece, rp->piece_data, size)); - } + m_ses.m_alerts.post_alert(read_piece_alert( + get_handle(), r.piece, rp->piece_data, size)); delete rp; } } diff --git a/src/torrent_handle.cpp b/src/torrent_handle.cpp index ffe3ff86f..c2bcba977 100644 --- a/src/torrent_handle.cpp +++ b/src/torrent_handle.cpp @@ -969,6 +969,11 @@ namespace libtorrent TORRENT_ASYNC_CALL1(reset_piece_deadline, index); } + boost::shared_ptr torrent_handle::native_handle() const + { + return m_torrent.lock(); + } + std::size_t hash_value(torrent_status const& ts) { return hash_value(ts.handle); @@ -978,5 +983,6 @@ namespace libtorrent { return std::size_t(th.m_torrent.lock().get()); } + }