forked from premiere/premiere-libtorrent
possible dangling pointer fix in broadcast_socket
This commit is contained in:
parent
b80aa035a2
commit
0a2b352795
|
@ -117,6 +117,9 @@ namespace libtorrent
|
||||||
void open_multicast_socket(io_service& ios, address const& addr
|
void open_multicast_socket(io_service& ios, address const& addr
|
||||||
, bool loopback, error_code& ec);
|
, bool loopback, error_code& ec);
|
||||||
|
|
||||||
|
// if we're aborting, destruct the handler and return true
|
||||||
|
bool maybe_abort();
|
||||||
|
|
||||||
// these sockets are used to
|
// these sockets are used to
|
||||||
// join the multicast group (on each interface)
|
// join the multicast group (on each interface)
|
||||||
// and receive multicast messages
|
// and receive multicast messages
|
||||||
|
@ -128,6 +131,18 @@ namespace libtorrent
|
||||||
std::list<socket_entry> m_unicast_sockets;
|
std::list<socket_entry> m_unicast_sockets;
|
||||||
udp::endpoint m_multicast_endpoint;
|
udp::endpoint m_multicast_endpoint;
|
||||||
receive_handler_t m_on_receive;
|
receive_handler_t m_on_receive;
|
||||||
|
|
||||||
|
// the number of outstanding async operations
|
||||||
|
// we have on these sockets. The m_on_receive
|
||||||
|
// handler may not be destructed until this reaches
|
||||||
|
// 0, since it may be holding references to
|
||||||
|
// the broadcast_socket itself.
|
||||||
|
int m_outstanding_operations;
|
||||||
|
// when set to true, we're trying to shut down
|
||||||
|
// don't initiate new operations and once the
|
||||||
|
// outstanding counter reaches 0, destruct
|
||||||
|
// the handler object
|
||||||
|
bool m_abort;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -217,6 +217,8 @@ namespace libtorrent
|
||||||
, bool loopback)
|
, bool loopback)
|
||||||
: m_multicast_endpoint(multicast_endpoint)
|
: m_multicast_endpoint(multicast_endpoint)
|
||||||
, m_on_receive(handler)
|
, m_on_receive(handler)
|
||||||
|
, m_outstanding_operations(0)
|
||||||
|
, m_abort(false)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(is_multicast(m_multicast_endpoint.address()));
|
TORRENT_ASSERT(is_multicast(m_multicast_endpoint.address()));
|
||||||
|
|
||||||
|
@ -279,6 +281,7 @@ namespace libtorrent
|
||||||
#endif
|
#endif
|
||||||
s->async_receive_from(asio::buffer(se.buffer, sizeof(se.buffer))
|
s->async_receive_from(asio::buffer(se.buffer, sizeof(se.buffer))
|
||||||
, se.remote, boost::bind(&broadcast_socket::on_receive, this, &se, _1, _2));
|
, se.remote, boost::bind(&broadcast_socket::on_receive, this, &se, _1, _2));
|
||||||
|
++m_outstanding_operations;
|
||||||
}
|
}
|
||||||
|
|
||||||
void broadcast_socket::open_unicast_socket(io_service& ios, address const& addr
|
void broadcast_socket::open_unicast_socket(io_service& ios, address const& addr
|
||||||
|
@ -305,6 +308,7 @@ namespace libtorrent
|
||||||
#endif
|
#endif
|
||||||
s->async_receive_from(asio::buffer(se.buffer, sizeof(se.buffer))
|
s->async_receive_from(asio::buffer(se.buffer, sizeof(se.buffer))
|
||||||
, se.remote, boost::bind(&broadcast_socket::on_receive, this, &se, _1, _2));
|
, se.remote, boost::bind(&broadcast_socket::on_receive, this, &se, _1, _2));
|
||||||
|
++m_outstanding_operations;
|
||||||
}
|
}
|
||||||
|
|
||||||
void broadcast_socket::send(char const* buffer, int size, error_code& ec, int flags)
|
void broadcast_socket::send(char const* buffer, int size, error_code& ec, int flags)
|
||||||
|
@ -365,14 +369,31 @@ namespace libtorrent
|
||||||
#if defined TORRENT_ASIO_DEBUGGING
|
#if defined TORRENT_ASIO_DEBUGGING
|
||||||
complete_async("broadcast_socket::on_receive");
|
complete_async("broadcast_socket::on_receive");
|
||||||
#endif
|
#endif
|
||||||
if (ec || bytes_transferred == 0 || !m_on_receive) return;
|
TORRENT_ASSERT(m_outstanding_operations > 0);
|
||||||
|
--m_outstanding_operations;
|
||||||
|
|
||||||
|
if (ec || bytes_transferred == 0 || !m_on_receive)
|
||||||
|
{
|
||||||
|
maybe_abort();
|
||||||
|
return;
|
||||||
|
}
|
||||||
m_on_receive(s->remote, s->buffer, bytes_transferred);
|
m_on_receive(s->remote, s->buffer, bytes_transferred);
|
||||||
|
|
||||||
|
if (maybe_abort()) return;
|
||||||
if (!s->socket) return;
|
if (!s->socket) return;
|
||||||
#if defined TORRENT_ASIO_DEBUGGING
|
#if defined TORRENT_ASIO_DEBUGGING
|
||||||
add_outstanding_async("broadcast_socket::on_receive");
|
add_outstanding_async("broadcast_socket::on_receive");
|
||||||
#endif
|
#endif
|
||||||
s->socket->async_receive_from(asio::buffer(s->buffer, sizeof(s->buffer))
|
s->socket->async_receive_from(asio::buffer(s->buffer, sizeof(s->buffer))
|
||||||
, s->remote, boost::bind(&broadcast_socket::on_receive, this, s, _1, _2));
|
, s->remote, boost::bind(&broadcast_socket::on_receive, this, s, _1, _2));
|
||||||
|
++m_outstanding_operations;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool broadcast_socket::maybe_abort()
|
||||||
|
{
|
||||||
|
if (m_abort && m_outstanding_operations == 0)
|
||||||
|
m_on_receive.clear();
|
||||||
|
return m_abort;
|
||||||
}
|
}
|
||||||
|
|
||||||
void broadcast_socket::close()
|
void broadcast_socket::close()
|
||||||
|
@ -380,7 +401,8 @@ namespace libtorrent
|
||||||
std::for_each(m_sockets.begin(), m_sockets.end(), boost::bind(&socket_entry::close, _1));
|
std::for_each(m_sockets.begin(), m_sockets.end(), boost::bind(&socket_entry::close, _1));
|
||||||
std::for_each(m_unicast_sockets.begin(), m_unicast_sockets.end(), boost::bind(&socket_entry::close, _1));
|
std::for_each(m_unicast_sockets.begin(), m_unicast_sockets.end(), boost::bind(&socket_entry::close, _1));
|
||||||
|
|
||||||
m_on_receive.clear();
|
m_abort = true;
|
||||||
|
maybe_abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1598,9 +1598,9 @@ namespace aux {
|
||||||
m_i2p_conn.close(ec);
|
m_i2p_conn.close(ec);
|
||||||
#endif
|
#endif
|
||||||
m_queued_for_checking.clear();
|
m_queued_for_checking.clear();
|
||||||
if (m_lsd) m_lsd->close();
|
stop_lsd();
|
||||||
if (m_upnp) m_upnp->close();
|
stop_upnp();
|
||||||
if (m_natpmp) m_natpmp->close();
|
stop_natpmp();
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
if (m_dht)
|
if (m_dht)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue