mirror of
https://github.com/boostorg/asio.git
synced 2026-01-27 06:32:08 +00:00
Don't free the reactor's per-descriptor state until after close.
This commit is contained in:
@@ -102,15 +102,21 @@ public:
|
||||
BOOST_ASIO_DECL void cancel_ops(socket_type descriptor, per_descriptor_data&);
|
||||
|
||||
// Cancel any operations that are running against the descriptor and remove
|
||||
// its registration from the reactor.
|
||||
// its registration from the reactor. The reactor resources associated with
|
||||
// the descriptor must be released by calling cleanup_descriptor_data.
|
||||
BOOST_ASIO_DECL void deregister_descriptor(socket_type descriptor,
|
||||
per_descriptor_data&, bool closing);
|
||||
|
||||
// Cancel any operations that are running against the descriptor and remove
|
||||
// its registration from the reactor.
|
||||
// Remove the descriptor's registration from the reactor. The reactor
|
||||
// resources associated with the descriptor must be released by calling
|
||||
// cleanup_descriptor_data.
|
||||
BOOST_ASIO_DECL void deregister_internal_descriptor(
|
||||
socket_type descriptor, per_descriptor_data&);
|
||||
|
||||
// Perform any post-deregistration cleanup tasks associated with the
|
||||
// descriptor data.
|
||||
BOOST_ASIO_DECL void cleanup_descriptor_data(per_descriptor_data&);
|
||||
|
||||
// Add a new timer queue to the reactor.
|
||||
template <typename Time_Traits>
|
||||
void add_timer_queue(timer_queue<Time_Traits>& queue);
|
||||
|
||||
@@ -123,14 +123,22 @@ public:
|
||||
per_descriptor_data& descriptor_data);
|
||||
|
||||
// Cancel any operations that are running against the descriptor and remove
|
||||
// its registration from the reactor.
|
||||
// its registration from the reactor. The reactor resources associated with
|
||||
// the descriptor must be released by calling cleanup_descriptor_data.
|
||||
BOOST_ASIO_DECL void deregister_descriptor(socket_type descriptor,
|
||||
per_descriptor_data& descriptor_data, bool closing);
|
||||
|
||||
// Remote the descriptor's registration from the reactor.
|
||||
// Remove the descriptor's registration from the reactor. The reactor
|
||||
// resources associated with the descriptor must be released by calling
|
||||
// cleanup_descriptor_data.
|
||||
BOOST_ASIO_DECL void deregister_internal_descriptor(
|
||||
socket_type descriptor, per_descriptor_data& descriptor_data);
|
||||
|
||||
// Perform any post-deregistration cleanup tasks associated with the
|
||||
// descriptor data.
|
||||
BOOST_ASIO_DECL void cleanup_descriptor_data(
|
||||
per_descriptor_data& descriptor_data);
|
||||
|
||||
// Add a new timer queue to the reactor.
|
||||
template <typename Time_Traits>
|
||||
void add_timer_queue(timer_queue<Time_Traits>& timer_queue);
|
||||
|
||||
@@ -235,6 +235,11 @@ void dev_poll_reactor::deregister_internal_descriptor(
|
||||
op_queue_[i].cancel_operations(descriptor, ops, ec);
|
||||
}
|
||||
|
||||
void dev_poll_reactor::cleanup_descriptor_data(
|
||||
dev_poll_reactor::per_descriptor_data&)
|
||||
{
|
||||
}
|
||||
|
||||
void dev_poll_reactor::run(bool block, op_queue<operation>& ops)
|
||||
{
|
||||
boost::asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
|
||||
@@ -359,9 +359,6 @@ void epoll_reactor::deregister_descriptor(socket_type descriptor,
|
||||
|
||||
descriptor_lock.unlock();
|
||||
|
||||
free_descriptor_state(descriptor_data);
|
||||
descriptor_data = 0;
|
||||
|
||||
io_service_.post_deferred_completions(ops);
|
||||
}
|
||||
}
|
||||
@@ -387,7 +384,14 @@ void epoll_reactor::deregister_internal_descriptor(socket_type descriptor,
|
||||
descriptor_data->shutdown_ = true;
|
||||
|
||||
descriptor_lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void epoll_reactor::cleanup_descriptor_data(
|
||||
per_descriptor_data& descriptor_data)
|
||||
{
|
||||
if (descriptor_data)
|
||||
{
|
||||
free_descriptor_state(descriptor_data);
|
||||
descriptor_data = 0;
|
||||
}
|
||||
|
||||
@@ -312,9 +312,6 @@ void kqueue_reactor::deregister_descriptor(socket_type descriptor,
|
||||
|
||||
descriptor_lock.unlock();
|
||||
|
||||
free_descriptor_state(descriptor_data);
|
||||
descriptor_data = 0;
|
||||
|
||||
io_service_.post_deferred_completions(ops);
|
||||
}
|
||||
}
|
||||
@@ -344,7 +341,14 @@ void kqueue_reactor::deregister_internal_descriptor(socket_type descriptor,
|
||||
descriptor_data->shutdown_ = true;
|
||||
|
||||
descriptor_lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void kqueue_reactor::cleanup_descriptor_data(
|
||||
per_descriptor_data& descriptor_data)
|
||||
{
|
||||
if (descriptor_data)
|
||||
{
|
||||
free_descriptor_state(descriptor_data);
|
||||
descriptor_data = 0;
|
||||
}
|
||||
|
||||
@@ -88,10 +88,12 @@ void reactive_descriptor_service::destroy(
|
||||
|
||||
reactor_.deregister_descriptor(impl.descriptor_, impl.reactor_data_,
|
||||
(impl.state_ & descriptor_ops::possible_dup) == 0);
|
||||
}
|
||||
|
||||
boost::system::error_code ignored_ec;
|
||||
descriptor_ops::close(impl.descriptor_, impl.state_, ignored_ec);
|
||||
boost::system::error_code ignored_ec;
|
||||
descriptor_ops::close(impl.descriptor_, impl.state_, ignored_ec);
|
||||
|
||||
reactor_.cleanup_descriptor_data(impl.reactor_data_);
|
||||
}
|
||||
}
|
||||
|
||||
boost::system::error_code reactive_descriptor_service::assign(
|
||||
@@ -128,9 +130,15 @@ boost::system::error_code reactive_descriptor_service::close(
|
||||
|
||||
reactor_.deregister_descriptor(impl.descriptor_, impl.reactor_data_,
|
||||
(impl.state_ & descriptor_ops::possible_dup) == 0);
|
||||
}
|
||||
|
||||
descriptor_ops::close(impl.descriptor_, impl.state_, ec);
|
||||
descriptor_ops::close(impl.descriptor_, impl.state_, ec);
|
||||
|
||||
reactor_.cleanup_descriptor_data(impl.reactor_data_);
|
||||
}
|
||||
else
|
||||
{
|
||||
ec = boost::system::error_code();
|
||||
}
|
||||
|
||||
// The descriptor is closed by the OS even if close() returns an error.
|
||||
//
|
||||
@@ -154,6 +162,7 @@ reactive_descriptor_service::release(
|
||||
BOOST_ASIO_HANDLER_OPERATION(("descriptor", &impl, "release"));
|
||||
|
||||
reactor_.deregister_descriptor(impl.descriptor_, impl.reactor_data_, false);
|
||||
reactor_.cleanup_descriptor_data(impl.reactor_data_);
|
||||
construct(impl);
|
||||
}
|
||||
|
||||
|
||||
@@ -89,6 +89,8 @@ void reactive_socket_service_base::destroy(
|
||||
|
||||
boost::system::error_code ignored_ec;
|
||||
socket_ops::close(impl.socket_, impl.state_, true, ignored_ec);
|
||||
|
||||
reactor_.cleanup_descriptor_data(impl.reactor_data_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,9 +104,15 @@ boost::system::error_code reactive_socket_service_base::close(
|
||||
|
||||
reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_,
|
||||
(impl.state_ & socket_ops::possible_dup) == 0);
|
||||
}
|
||||
|
||||
socket_ops::close(impl.socket_, impl.state_, false, ec);
|
||||
socket_ops::close(impl.socket_, impl.state_, false, ec);
|
||||
|
||||
reactor_.cleanup_descriptor_data(impl.reactor_data_);
|
||||
}
|
||||
else
|
||||
{
|
||||
ec = boost::system::error_code();
|
||||
}
|
||||
|
||||
// The descriptor is closed by the OS even if close() returns an error.
|
||||
//
|
||||
|
||||
@@ -163,6 +163,11 @@ void select_reactor::deregister_internal_descriptor(
|
||||
op_queue_[i].cancel_operations(descriptor, ops);
|
||||
}
|
||||
|
||||
void select_reactor::cleanup_descriptor_data(
|
||||
select_reactor::per_descriptor_data&)
|
||||
{
|
||||
}
|
||||
|
||||
void select_reactor::run(bool block, op_queue<operation>& ops)
|
||||
{
|
||||
boost::asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
|
||||
@@ -187,6 +187,7 @@ void signal_set_service::fork_service(
|
||||
state->fork_prepared_ = true;
|
||||
lock.unlock();
|
||||
reactor_.deregister_internal_descriptor(read_descriptor, reactor_data_);
|
||||
reactor_.cleanup_descriptor_data(reactor_data_);
|
||||
}
|
||||
break;
|
||||
case boost::asio::io_service::fork_parent:
|
||||
@@ -541,6 +542,7 @@ void signal_set_service::remove_service(signal_set_service* service)
|
||||
lock.unlock();
|
||||
service->reactor_.deregister_descriptor(
|
||||
read_descriptor, service->reactor_data_, false);
|
||||
service->reactor_.cleanup_descriptor_data(service->reactor_data_);
|
||||
lock.lock();
|
||||
#endif // !defined(BOOST_ASIO_WINDOWS)
|
||||
// && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
||||
|
||||
@@ -177,9 +177,16 @@ boost::system::error_code win_iocp_socket_service_base::close(
|
||||
reinterpret_cast<void**>(&reactor_), 0, 0));
|
||||
if (r)
|
||||
r->deregister_descriptor(impl.socket_, impl.reactor_data_, true);
|
||||
}
|
||||
|
||||
socket_ops::close(impl.socket_, impl.state_, false, ec);
|
||||
socket_ops::close(impl.socket_, impl.state_, false, ec);
|
||||
|
||||
if (r)
|
||||
r->cleanup_descriptor_data(impl.reactor_data_);
|
||||
}
|
||||
else
|
||||
{
|
||||
ec = boost::system::error_code();
|
||||
}
|
||||
|
||||
impl.socket_ = invalid_socket;
|
||||
impl.state_ = 0;
|
||||
@@ -629,10 +636,14 @@ void win_iocp_socket_service_base::close_for_destruction(
|
||||
reinterpret_cast<void**>(&reactor_), 0, 0));
|
||||
if (r)
|
||||
r->deregister_descriptor(impl.socket_, impl.reactor_data_, true);
|
||||
|
||||
boost::system::error_code ignored_ec;
|
||||
socket_ops::close(impl.socket_, impl.state_, true, ignored_ec);
|
||||
|
||||
if (r)
|
||||
r->cleanup_descriptor_data(impl.reactor_data_);
|
||||
}
|
||||
|
||||
boost::system::error_code ignored_ec;
|
||||
socket_ops::close(impl.socket_, impl.state_, true, ignored_ec);
|
||||
impl.socket_ = invalid_socket;
|
||||
impl.state_ = 0;
|
||||
impl.cancel_token_.reset();
|
||||
|
||||
@@ -125,14 +125,22 @@ public:
|
||||
per_descriptor_data& descriptor_data);
|
||||
|
||||
// Cancel any operations that are running against the descriptor and remove
|
||||
// its registration from the reactor.
|
||||
// its registration from the reactor. The reactor resources associated with
|
||||
// the descriptor must be released by calling cleanup_descriptor_data.
|
||||
BOOST_ASIO_DECL void deregister_descriptor(socket_type descriptor,
|
||||
per_descriptor_data& descriptor_data, bool closing);
|
||||
|
||||
// Remote the descriptor's registration from the reactor.
|
||||
// Remove the descriptor's registration from the reactor. The reactor
|
||||
// resources associated with the descriptor must be released by calling
|
||||
// cleanup_descriptor_data.
|
||||
BOOST_ASIO_DECL void deregister_internal_descriptor(
|
||||
socket_type descriptor, per_descriptor_data& descriptor_data);
|
||||
|
||||
// Perform any post-deregistration cleanup tasks associated with the
|
||||
// descriptor data.
|
||||
BOOST_ASIO_DECL void cleanup_descriptor_data(
|
||||
per_descriptor_data& descriptor_data);
|
||||
|
||||
// Add a new timer queue to the reactor.
|
||||
template <typename Time_Traits>
|
||||
void add_timer_queue(timer_queue<Time_Traits>& queue);
|
||||
|
||||
@@ -107,13 +107,20 @@ public:
|
||||
BOOST_ASIO_DECL void cancel_ops(socket_type descriptor, per_descriptor_data&);
|
||||
|
||||
// Cancel any operations that are running against the descriptor and remove
|
||||
// its registration from the reactor.
|
||||
// its registration from the reactor. The reactor resources associated with
|
||||
// the descriptor must be released by calling cleanup_descriptor_data.
|
||||
BOOST_ASIO_DECL void deregister_descriptor(socket_type descriptor,
|
||||
per_descriptor_data&, bool closing);
|
||||
|
||||
// Remote the descriptor's registration from the reactor.
|
||||
// Remove the descriptor's registration from the reactor. The reactor
|
||||
// resources associated with the descriptor must be released by calling
|
||||
// cleanup_descriptor_data.
|
||||
BOOST_ASIO_DECL void deregister_internal_descriptor(
|
||||
socket_type descriptor, per_descriptor_data& descriptor_data);
|
||||
socket_type descriptor, per_descriptor_data&);
|
||||
|
||||
// Perform any post-deregistration cleanup tasks associated with the
|
||||
// descriptor data.
|
||||
BOOST_ASIO_DECL void cleanup_descriptor_data(per_descriptor_data&);
|
||||
|
||||
// Move descriptor registration from one descriptor_data object to another.
|
||||
BOOST_ASIO_DECL void move_descriptor(socket_type descriptor,
|
||||
|
||||
Reference in New Issue
Block a user