diff options
Diffstat (limited to 'boost/process/detail/posix/sigchld_service.hpp')
-rw-r--r-- | boost/process/detail/posix/sigchld_service.hpp | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/boost/process/detail/posix/sigchld_service.hpp b/boost/process/detail/posix/sigchld_service.hpp index 3e7d12d95d..820f0e81a3 100644 --- a/boost/process/detail/posix/sigchld_service.hpp +++ b/boost/process/detail/posix/sigchld_service.hpp @@ -7,6 +7,8 @@ #ifndef BOOST_PROCESS_DETAIL_POSIX_SIGCHLD_SERVICE_HPP_ #define BOOST_PROCESS_DETAIL_POSIX_SIGCHLD_SERVICE_HPP_ +#include <boost/asio/dispatch.hpp> +#include <boost/asio/post.hpp> #include <boost/asio/signal_set.hpp> #include <boost/asio/strand.hpp> #include <boost/optional.hpp> @@ -36,22 +38,34 @@ public: { boost::asio::async_completion< SignalHandler, void(boost::system::error_code)> init{handler}; + auto & h = init.completion_handler; - _strand.post( + boost::asio::dispatch( + _strand, [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); + //check if the child actually is running first + int status; + auto pid_res = ::waitpid(pid, &status, WNOHANG); + if (pid_res < 0) + h(-1, get_last_error()); + else if ((pid_res == pid) && (WIFEXITED(status) || WIFSIGNALED(status))) + h(status, {}); //successfully exited already + else //still running + { + if (_receivers.empty()) + _signal_set.async_wait( + [this](const boost::system::error_code &ec, int) + { + boost::asio::dispatch(_strand, [this, ec]{this->_handle_signal(ec);}); + }); + _receivers.emplace_back(pid, h); + } }); return init.result.get(); } - void shutdown_service() override + void shutdown() override { _receivers.clear(); } @@ -104,7 +118,7 @@ void sigchld_service::_handle_signal(const boost::system::error_code & ec) _signal_set.async_wait( [this](const boost::system::error_code & ec, int) { - _strand.post([this, ec]{this->_handle_signal(ec);}); + boost::asio::post(_strand, [this, ec]{this->_handle_signal(ec);}); }); } } |