diff options
Diffstat (limited to 'boost/asio/detail/impl')
-rw-r--r-- | boost/asio/detail/impl/dev_poll_reactor.ipp | 5 | ||||
-rw-r--r-- | boost/asio/detail/impl/epoll_reactor.ipp | 39 | ||||
-rw-r--r-- | boost/asio/detail/impl/kqueue_reactor.ipp | 28 | ||||
-rw-r--r-- | boost/asio/detail/impl/reactive_descriptor_service.ipp | 19 | ||||
-rw-r--r-- | boost/asio/detail/impl/reactive_socket_service_base.ipp | 14 | ||||
-rw-r--r-- | boost/asio/detail/impl/select_reactor.ipp | 5 | ||||
-rw-r--r-- | boost/asio/detail/impl/signal_set_service.ipp | 6 | ||||
-rw-r--r-- | boost/asio/detail/impl/win_iocp_socket_service_base.ipp | 19 |
8 files changed, 113 insertions, 22 deletions
diff --git a/boost/asio/detail/impl/dev_poll_reactor.ipp b/boost/asio/detail/impl/dev_poll_reactor.ipp index efe2ba7086..7efb05ed02 100644 --- a/boost/asio/detail/impl/dev_poll_reactor.ipp +++ b/boost/asio/detail/impl/dev_poll_reactor.ipp @@ -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_); diff --git a/boost/asio/detail/impl/epoll_reactor.ipp b/boost/asio/detail/impl/epoll_reactor.ipp index 610ce31ce5..3d3d244e0a 100644 --- a/boost/asio/detail/impl/epoll_reactor.ipp +++ b/boost/asio/detail/impl/epoll_reactor.ipp @@ -359,10 +359,16 @@ 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); + + // Leave descriptor_data set so that it will be freed by the subsequent + // call to cleanup_descriptor_data. + } + else + { + // We are shutting down, so prevent cleanup_descriptor_data from freeing + // the descriptor_data object and let the destructor free it instead. + descriptor_data = 0; } } @@ -388,6 +394,22 @@ void epoll_reactor::deregister_internal_descriptor(socket_type descriptor, descriptor_lock.unlock(); + // Leave descriptor_data set so that it will be freed by the subsequent + // call to cleanup_descriptor_data. + } + else + { + // We are shutting down, so prevent cleanup_descriptor_data from freeing + // the descriptor_data object and let the destructor free it instead. + descriptor_data = 0; + } +} + +void epoll_reactor::cleanup_descriptor_data( + per_descriptor_data& descriptor_data) +{ + if (descriptor_data) + { free_descriptor_state(descriptor_data); descriptor_data = 0; } @@ -451,8 +473,15 @@ void epoll_reactor::run(bool block, op_queue<operation>& ops) // don't call work_started() here. This still allows the io_service to // stop if the only remaining operations are descriptor operations. descriptor_state* descriptor_data = static_cast<descriptor_state*>(ptr); - descriptor_data->set_ready_events(events[i].events); - ops.push(descriptor_data); + if (!ops.is_enqueued(descriptor_data)) + { + descriptor_data->set_ready_events(events[i].events); + ops.push(descriptor_data); + } + else + { + descriptor_data->add_ready_events(events[i].events); + } } } diff --git a/boost/asio/detail/impl/kqueue_reactor.ipp b/boost/asio/detail/impl/kqueue_reactor.ipp index b4a7a10b71..8057606ce6 100644 --- a/boost/asio/detail/impl/kqueue_reactor.ipp +++ b/boost/asio/detail/impl/kqueue_reactor.ipp @@ -312,10 +312,16 @@ 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); + + // Leave descriptor_data set so that it will be freed by the subsequent + // call to cleanup_descriptor_data. + } + else + { + // We are shutting down, so prevent cleanup_descriptor_data from freeing + // the descriptor_data object and let the destructor free it instead. + descriptor_data = 0; } } @@ -345,6 +351,22 @@ void kqueue_reactor::deregister_internal_descriptor(socket_type descriptor, descriptor_lock.unlock(); + // Leave descriptor_data set so that it will be freed by the subsequent + // call to cleanup_descriptor_data. + } + else + { + // We are shutting down, so prevent cleanup_descriptor_data from freeing + // the descriptor_data object and let the destructor free it instead. + descriptor_data = 0; + } +} + +void kqueue_reactor::cleanup_descriptor_data( + per_descriptor_data& descriptor_data) +{ + if (descriptor_data) + { free_descriptor_state(descriptor_data); descriptor_data = 0; } diff --git a/boost/asio/detail/impl/reactive_descriptor_service.ipp b/boost/asio/detail/impl/reactive_descriptor_service.ipp index 56caec9fd3..a0300c47d0 100644 --- a/boost/asio/detail/impl/reactive_descriptor_service.ipp +++ b/boost/asio/detail/impl/reactive_descriptor_service.ipp @@ -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); } diff --git a/boost/asio/detail/impl/reactive_socket_service_base.ipp b/boost/asio/detail/impl/reactive_socket_service_base.ipp index 21e77e9f93..3594ae0528 100644 --- a/boost/asio/detail/impl/reactive_socket_service_base.ipp +++ b/boost/asio/detail/impl/reactive_socket_service_base.ipp @@ -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. // @@ -224,7 +232,7 @@ void reactive_socket_service_base::start_accept_op( reactor_op* op, bool is_continuation, bool peer_is_open) { if (!peer_is_open) - start_op(impl, reactor::read_op, op, true, is_continuation, false); + start_op(impl, reactor::read_op, op, is_continuation, true, false); else { op->ec_ = boost::asio::error::already_open; diff --git a/boost/asio/detail/impl/select_reactor.ipp b/boost/asio/detail/impl/select_reactor.ipp index 80686eaf97..869f73492b 100644 --- a/boost/asio/detail/impl/select_reactor.ipp +++ b/boost/asio/detail/impl/select_reactor.ipp @@ -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_); diff --git a/boost/asio/detail/impl/signal_set_service.ipp b/boost/asio/detail/impl/signal_set_service.ipp index 56313e0923..95ea8bee21 100644 --- a/boost/asio/detail/impl/signal_set_service.ipp +++ b/boost/asio/detail/impl/signal_set_service.ipp @@ -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: @@ -539,8 +540,9 @@ void signal_set_service::remove_service(signal_set_service* service) // Disable the pipe readiness notifications. int read_descriptor = state->read_descriptor_; lock.unlock(); - service->reactor_.deregister_descriptor( - read_descriptor, service->reactor_data_, false); + service->reactor_.deregister_internal_descriptor( + read_descriptor, service->reactor_data_); + service->reactor_.cleanup_descriptor_data(service->reactor_data_); lock.lock(); #endif // !defined(BOOST_ASIO_WINDOWS) // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) diff --git a/boost/asio/detail/impl/win_iocp_socket_service_base.ipp b/boost/asio/detail/impl/win_iocp_socket_service_base.ipp index 22818f7e92..93f5ed0713 100644 --- a/boost/asio/detail/impl/win_iocp_socket_service_base.ipp +++ b/boost/asio/detail/impl/win_iocp_socket_service_base.ipp @@ -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(); |