diff options
author | Kevin Smith <git@kismith.co.uk> | 2012-08-02 20:41:55 (GMT) |
---|---|---|
committer | Kevin Smith <git@kismith.co.uk> | 2012-08-02 21:03:09 (GMT) |
commit | d5ace22054203c7989691ae8b3fa4e4784d1b57e (patch) | |
tree | 64d400cdb10644967df183d0f202fcbf8160a773 /3rdParty/Boost/src/boost/asio/detail/impl/kqueue_reactor.ipp | |
parent | 6f26d9aa86f0909af13b23b1a925b8d492e74154 (diff) | |
download | swift-contrib-d5ace22054203c7989691ae8b3fa4e4784d1b57e.zip swift-contrib-d5ace22054203c7989691ae8b3fa4e4784d1b57e.tar.bz2 |
Add two extra Boost dependencies, upgrade to 1.47.0ks/boost1.47
Diffstat (limited to '3rdParty/Boost/src/boost/asio/detail/impl/kqueue_reactor.ipp')
-rw-r--r-- | 3rdParty/Boost/src/boost/asio/detail/impl/kqueue_reactor.ipp | 139 |
1 files changed, 134 insertions, 5 deletions
diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/kqueue_reactor.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/kqueue_reactor.ipp index 3ac9eae..f56c4c7 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/kqueue_reactor.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/kqueue_reactor.ipp @@ -75,6 +75,47 @@ void kqueue_reactor::shutdown_service() } timer_queues_.get_all_timers(ops); + + io_service_.abandon_operations(ops); +} + +void kqueue_reactor::fork_service(boost::asio::io_service::fork_event fork_ev) +{ + if (fork_ev == boost::asio::io_service::fork_child) + { + // The kqueue descriptor is automatically closed in the child. + kqueue_fd_ = -1; + kqueue_fd_ = do_kqueue_create(); + + interrupter_.recreate(); + + // Re-register all descriptors with kqueue. + mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_); + for (descriptor_state* state = registered_descriptors_.first(); + state != 0; state = state->next_) + { + struct kevent events[2]; + int num_events = 0; + + if (!state->op_queue_[read_op].empty()) + BOOST_ASIO_KQUEUE_EV_SET(&events[num_events++], state->descriptor_, + EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, state); + else if (!state->op_queue_[except_op].empty()) + BOOST_ASIO_KQUEUE_EV_SET(&events[num_events++], state->descriptor_, + EVFILT_READ, EV_ADD | EV_CLEAR, EV_OOBAND, 0, state); + + if (!state->op_queue_[write_op].empty()) + BOOST_ASIO_KQUEUE_EV_SET(&events[num_events++], state->descriptor_, + EVFILT_WRITE, EV_ADD | EV_CLEAR, 0, 0, state); + + if (num_events && ::kevent(kqueue_fd_, events, num_events, 0, 0, 0) == -1) + { + boost::system::error_code error(errno, + boost::asio::error::get_system_category()); + boost::asio::detail::throw_error(error); + } + } + } } void kqueue_reactor::init_task() @@ -82,17 +123,58 @@ void kqueue_reactor::init_task() io_service_.init_task(); } -int kqueue_reactor::register_descriptor(socket_type, +int kqueue_reactor::register_descriptor(socket_type descriptor, kqueue_reactor::per_descriptor_data& descriptor_data) { mutex::scoped_lock lock(registered_descriptors_mutex_); descriptor_data = registered_descriptors_.alloc(); + descriptor_data->descriptor_ = descriptor; descriptor_data->shutdown_ = false; return 0; } +int kqueue_reactor::register_internal_descriptor( + int op_type, socket_type descriptor, + kqueue_reactor::per_descriptor_data& descriptor_data, reactor_op* op) +{ + mutex::scoped_lock lock(registered_descriptors_mutex_); + + descriptor_data = registered_descriptors_.alloc(); + descriptor_data->descriptor_ = descriptor; + descriptor_data->shutdown_ = false; + descriptor_data->op_queue_[op_type].push(op); + + struct kevent event; + switch (op_type) + { + case read_op: + BOOST_ASIO_KQUEUE_EV_SET(&event, descriptor, EVFILT_READ, + EV_ADD | EV_CLEAR, 0, 0, descriptor_data); + break; + case write_op: + BOOST_ASIO_KQUEUE_EV_SET(&event, descriptor, EVFILT_WRITE, + EV_ADD | EV_CLEAR, 0, 0, descriptor_data); + break; + case except_op: + BOOST_ASIO_KQUEUE_EV_SET(&event, descriptor, EVFILT_READ, + EV_ADD | EV_CLEAR, EV_OOBAND, 0, descriptor_data); + break; + } + ::kevent(kqueue_fd_, &event, 1, 0, 0, 0); + + return 0; +} + +void kqueue_reactor::move_descriptor(socket_type, + kqueue_reactor::per_descriptor_data& target_descriptor_data, + kqueue_reactor::per_descriptor_data& source_descriptor_data) +{ + target_descriptor_data = source_descriptor_data; + source_descriptor_data = 0; +} + void kqueue_reactor::start_op(int op_type, socket_type descriptor, kqueue_reactor::per_descriptor_data& descriptor_data, reactor_op* op, bool allow_speculative) @@ -187,8 +269,8 @@ void kqueue_reactor::cancel_ops(socket_type, io_service_.post_deferred_completions(ops); } -void kqueue_reactor::close_descriptor(socket_type, - kqueue_reactor::per_descriptor_data& descriptor_data) +void kqueue_reactor::deregister_descriptor(socket_type descriptor, + kqueue_reactor::per_descriptor_data& descriptor_data, bool closing) { if (!descriptor_data) return; @@ -198,8 +280,20 @@ void kqueue_reactor::close_descriptor(socket_type, if (!descriptor_data->shutdown_) { - // Remove the descriptor from the set of known descriptors. The descriptor - // will be automatically removed from the kqueue set when it is closed. + if (closing) + { + // The descriptor will be automatically removed from the kqueue when it + // is closed. + } + else + { + struct kevent events[2]; + BOOST_ASIO_KQUEUE_EV_SET(&events[0], descriptor, + EVFILT_READ, EV_DELETE, 0, 0, 0); + BOOST_ASIO_KQUEUE_EV_SET(&events[1], descriptor, + EVFILT_WRITE, EV_DELETE, 0, 0, 0); + ::kevent(kqueue_fd_, events, 2, 0, 0, 0); + } op_queue<operation> ops; for (int i = 0; i < max_ops; ++i) @@ -212,6 +306,7 @@ void kqueue_reactor::close_descriptor(socket_type, } } + descriptor_data->descriptor_ = -1; descriptor_data->shutdown_ = true; descriptor_lock.unlock(); @@ -225,6 +320,40 @@ void kqueue_reactor::close_descriptor(socket_type, } } +void kqueue_reactor::deregister_internal_descriptor(socket_type descriptor, + kqueue_reactor::per_descriptor_data& descriptor_data) +{ + if (!descriptor_data) + return; + + mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); + mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_); + + if (!descriptor_data->shutdown_) + { + struct kevent events[2]; + BOOST_ASIO_KQUEUE_EV_SET(&events[0], descriptor, + EVFILT_READ, EV_DELETE, 0, 0, 0); + BOOST_ASIO_KQUEUE_EV_SET(&events[1], descriptor, + EVFILT_WRITE, EV_DELETE, 0, 0, 0); + ::kevent(kqueue_fd_, events, 2, 0, 0, 0); + + op_queue<operation> ops; + for (int i = 0; i < max_ops; ++i) + ops.push(descriptor_data->op_queue_[i]); + + descriptor_data->descriptor_ = -1; + descriptor_data->shutdown_ = true; + + descriptor_lock.unlock(); + + registered_descriptors_.free(descriptor_data); + descriptor_data = 0; + + descriptors_lock.unlock(); + } +} + void kqueue_reactor::run(bool block, op_queue<operation>& ops) { mutex::scoped_lock lock(mutex_); |