2
0
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:
Christopher Kohlhoff
2017-07-31 18:43:31 +10:00
parent 4d1b169964
commit 3541ec2eb9
12 changed files with 104 additions and 27 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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_);

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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.
//

View File

@@ -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_);

View File

@@ -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)

View File

@@ -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();

View File

@@ -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);

View File

@@ -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,