fix shutdown issue caused by peer connections being kept alive by disk buffer pool callbacks

This commit is contained in:
arvidn 2016-03-15 21:10:58 -04:00
parent 08bac479be
commit 36d0cfe40d
3 changed files with 24 additions and 19 deletions

View File

@ -135,7 +135,7 @@ namespace libtorrent
// of buffers in use drops below the low watermark, // of buffers in use drops below the low watermark,
// we start calling these functions back // we start calling these functions back
// TODO: try to remove the observers, only using the async_allocate handlers // TODO: try to remove the observers, only using the async_allocate handlers
std::vector<boost::shared_ptr<disk_observer> > m_observers; std::vector<boost::weak_ptr<disk_observer> > m_observers;
// these handlers are executed when a new buffer is available // these handlers are executed when a new buffer is available
std::vector<handler_t> m_handlers; std::vector<handler_t> m_handlers;

View File

@ -64,8 +64,10 @@ POSSIBILITY OF SUCH DAMAGE.
namespace libtorrent namespace libtorrent
{ {
namespace {
// this is posted to the network thread // this is posted to the network thread
static void watermark_callback(std::vector<boost::shared_ptr<disk_observer> >* cbs void watermark_callback(std::vector<boost::weak_ptr<disk_observer> >* cbs
, std::vector<disk_buffer_pool::handler_t>* handlers) , std::vector<disk_buffer_pool::handler_t>* handlers)
{ {
if (handlers) if (handlers)
@ -78,13 +80,18 @@ namespace libtorrent
if (cbs != NULL) if (cbs != NULL)
{ {
for (std::vector<boost::shared_ptr<disk_observer> >::iterator i = cbs->begin() for (std::vector<boost::weak_ptr<disk_observer> >::iterator i = cbs->begin()
, end(cbs->end()); i != end; ++i) , end(cbs->end()); i != end; ++i)
(*i)->on_disk(); {
boost::shared_ptr<disk_observer> o = i->lock();
if (o) o->on_disk();
}
delete cbs; delete cbs;
} }
} }
} // anonymous namespace
disk_buffer_pool::disk_buffer_pool(int block_size, io_service& ios disk_buffer_pool::disk_buffer_pool(int block_size, io_service& ios
, boost::function<void()> const& trigger_trim) , boost::function<void()> const& trigger_trim)
: m_block_size(block_size) : m_block_size(block_size)
@ -183,7 +190,7 @@ namespace libtorrent
{ {
l.unlock(); l.unlock();
m_ios.post(boost::bind(&watermark_callback m_ios.post(boost::bind(&watermark_callback
, static_cast<std::vector<boost::shared_ptr<disk_observer> >*>(NULL) , static_cast<std::vector<boost::weak_ptr<disk_observer> >*>(NULL)
, slice)); , slice));
return; return;
} }
@ -195,13 +202,13 @@ namespace libtorrent
{ {
l.unlock(); l.unlock();
m_ios.post(boost::bind(&watermark_callback m_ios.post(boost::bind(&watermark_callback
, static_cast<std::vector<boost::shared_ptr<disk_observer> >*>(NULL) , static_cast<std::vector<boost::weak_ptr<disk_observer> >*>(NULL)
, handlers)); , handlers));
return; return;
} }
std::vector<boost::shared_ptr<disk_observer> >* cbs std::vector<boost::weak_ptr<disk_observer> >* cbs
= new std::vector<boost::shared_ptr<disk_observer> >(); = new std::vector<boost::weak_ptr<disk_observer> >();
m_observers.swap(*cbs); m_observers.swap(*cbs);
l.unlock(); l.unlock();
m_ios.post(boost::bind(&watermark_callback, cbs, handlers)); m_ios.post(boost::bind(&watermark_callback, cbs, handlers));

View File

@ -1153,17 +1153,6 @@ namespace aux {
TORRENT_ASSERT_VAL(conn == int(m_connections.size()) + 1, conn); TORRENT_ASSERT_VAL(conn == int(m_connections.size()) + 1, conn);
} }
m_download_rate.close();
m_upload_rate.close();
// #error closing the udp socket here means that
// the uTP connections cannot be closed gracefully
m_udp_socket.close();
m_external_udp_port = 0;
#ifdef TORRENT_USE_OPENSSL
m_ssl_udp_socket.close();
#endif
// we need to give all the sockets an opportunity to actually have their handlers // we need to give all the sockets an opportunity to actually have their handlers
// called and cancelled before we continue the shutdown. This is a bit // called and cancelled before we continue the shutdown. This is a bit
// complicated, if there are no "undead" peers, it's safe tor resume the // complicated, if there are no "undead" peers, it's safe tor resume the
@ -1179,6 +1168,15 @@ namespace aux {
void session_impl::abort_stage2() void session_impl::abort_stage2()
{ {
m_download_rate.close();
m_upload_rate.close();
m_udp_socket.close();
m_external_udp_port = 0;
#ifdef TORRENT_USE_OPENSSL
m_ssl_udp_socket.close();
#endif
// it's OK to detach the threads here. The disk_io_thread // it's OK to detach the threads here. The disk_io_thread
// has an internal counter and won't release the network // has an internal counter and won't release the network
// thread until they're all dead (via m_work). // thread until they're all dead (via m_work).