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,
// we start calling these functions back
// 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
std::vector<handler_t> m_handlers;

View File

@ -64,8 +64,10 @@ POSSIBILITY OF SUCH DAMAGE.
namespace libtorrent
{
namespace {
// 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)
{
if (handlers)
@ -78,13 +80,18 @@ namespace libtorrent
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)
(*i)->on_disk();
{
boost::shared_ptr<disk_observer> o = i->lock();
if (o) o->on_disk();
}
delete cbs;
}
}
} // anonymous namespace
disk_buffer_pool::disk_buffer_pool(int block_size, io_service& ios
, boost::function<void()> const& trigger_trim)
: m_block_size(block_size)
@ -183,7 +190,7 @@ namespace libtorrent
{
l.unlock();
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));
return;
}
@ -195,13 +202,13 @@ namespace libtorrent
{
l.unlock();
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));
return;
}
std::vector<boost::shared_ptr<disk_observer> >* cbs
= new std::vector<boost::shared_ptr<disk_observer> >();
std::vector<boost::weak_ptr<disk_observer> >* cbs
= new std::vector<boost::weak_ptr<disk_observer> >();
m_observers.swap(*cbs);
l.unlock();
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);
}
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
// 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
@ -1179,6 +1168,15 @@ namespace aux {
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
// has an internal counter and won't release the network
// thread until they're all dead (via m_work).