From da34b4020db2c300b2189a39f514b0456a18b8e2 Mon Sep 17 00:00:00 2001 From: Klemens David Morgenstern Date: Tue, 1 Aug 2017 18:41:55 -0400 Subject: [PATCH] Trying to get the sigchld-service to work --- .../process/detail/posix/io_service_ref.hpp | 13 +-- .../process/detail/posix/sigchld_service.hpp | 81 +++++++++++-------- 2 files changed, 51 insertions(+), 43 deletions(-) diff --git a/include/boost/process/detail/posix/io_service_ref.hpp b/include/boost/process/detail/posix/io_service_ref.hpp index c845b19f..dde5fd55 100644 --- a/include/boost/process/detail/posix/io_service_ref.hpp +++ b/include/boost/process/detail/posix/io_service_ref.hpp @@ -74,16 +74,10 @@ struct io_service_ref : handler_base_ext } boost::asio::io_service &get() {return ios;}; - - //::boost::process::detail::posix::sigchld_service service{boost::asio::}; - + template void on_success(Executor& exec) { - - auto &service = boost::asio::use_service< - ::boost::process::detail::posix::sigchld_service>(ios); - //must be on the heap so I can move it into the lambda. auto asyncs = boost::fusion::filter_if< is_async_handler< @@ -102,16 +96,17 @@ struct io_service_ref : handler_base_ext auto wh = [funcs, es](int val, const std::error_code & ec) { - es.store(val); + es->store(val); for (auto & func : funcs) func(val, ec); }; - service.async_wait(exec.pid, std::move(wh)); + sigchld_service.async_wait(exec.pid, std::move(wh)); } private: boost::asio::io_service &ios; + boost::process::detail::posix::sigchld_service &sigchld_service = boost::asio::use_service(ios); }; }}}} diff --git a/include/boost/process/detail/posix/sigchld_service.hpp b/include/boost/process/detail/posix/sigchld_service.hpp index 6c35bd8c..abea94d4 100644 --- a/include/boost/process/detail/posix/sigchld_service.hpp +++ b/include/boost/process/detail/posix/sigchld_service.hpp @@ -8,9 +8,11 @@ #define BOOST_PROCESS_DETAIL_POSIX_SIGCHLD_SERVICE_HPP_ #include +#include #include #include #include +#include namespace boost { namespace process { namespace detail { namespace posix { @@ -32,60 +34,71 @@ public: void (int, std::error_code)) async_wait(::pid_t pid, SignalHandler && handler) { - boost::asio::detail::async_result_init< - SignalHandler, void(boost::system::error_code)> init{std::forward(handler)}; - - auto & h = init.handler; - _strand.post( - [pid, h] - { - if (_receivers.empty()) - _signal_set.async_wait( - [this](const boost::system::error_code & ec, int) - { - _strand.post([ec]{}); - this->_handle_signal(ec); - }); - _receivers.emplace_back(pid, h); - }); + boost::asio::detail::async_result_init< + SignalHandler, void(boost::system::error_code)> init{std::forward(handler)}; + auto & h = init.handler; + _strand.post( + [this, pid, h] + { + if (_receivers.empty()) + _signal_set.async_wait( + [this](const boost::system::error_code & ec, int) + { + _strand.post([this,ec]{this->_handle_signal(ec);}); + }); + _receivers.emplace_back(pid, h); + }); return init.result.get(); } + void shutdown_service() override + { + _receivers.clear(); + } void cancel() { - _signal_set.cancel(); + _signal_set.cancel(); } void cancel(boost::system::error_code & ec) { - _signal_set.cancel(ec); + _signal_set.cancel(ec); } }; void sigchld_service::_handle_signal(const boost::system::error_code & ec) { - std::error_code ec_{ec.value(), std::system_category()}; + std::error_code ec_{ec.value(), std::system_category()}; - if (ec_) - { - for (auto & r : _receivers) - r.second(-1, ec_); - } - pid_t pid; - int status; - int ret = ::waitpid(pid, &status, WNOHANG); + if (ec_) + { + for (auto & r : _receivers) + r.second(-1, ec_); + return; + } + int status; + int pid = ::waitpid(0, &status, WNOHANG); auto itr = std::find_if(_receivers.cbegin(), _receivers.cend(), - [](const std::pair<::pid_t, std::function> & p) - { - return p.first == pid; - }); - + [&pid](const std::pair<::pid_t, std::function> & p) + { + return p.first == pid; + }); if (itr != _receivers.cend()) { - itr->second(WEXITSTATUS(ret), ec_); - _receivers.erase(itr); + _strand.get_io_service().wrap(itr->second)(WEXITSTATUS(status), ec_); + //itr->second(WEXITSTATUS(ret), ec_); + _receivers.erase(itr); + } + if (!_receivers.empty()) + { + _signal_set.async_wait( + [this](const boost::system::error_code & ec, int) + { + _strand.post([ec]{}); + this->_handle_signal(ec); + }); } }