2
0
mirror of https://github.com/boostorg/process.git synced 2026-02-01 08:42:15 +00:00

Trying to get the sigchld-service to work

This commit is contained in:
Klemens David Morgenstern
2017-08-01 18:41:55 -04:00
parent 99001ccb50
commit da34b4020d
2 changed files with 51 additions and 43 deletions

View File

@@ -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 <class Executor>
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<boost::process::detail::posix::sigchld_service>(ios);
};
}}}}

View File

@@ -8,9 +8,11 @@
#define BOOST_PROCESS_DETAIL_POSIX_SIGCHLD_SERVICE_HPP_
#include <boost/asio/signal_set.hpp>
#include <boost/asio/strand.hpp>
#include <boost/optional.hpp>
#include <signal.h>
#include <functional>
#include <sys/wait.h>
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<SignalHandler>(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<SignalHandler>(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<void(int, std::error_code)>> & p)
{
return p.first == pid;
});
[&pid](const std::pair<::pid_t, std::function<void(int, std::error_code)>> & 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);
});
}
}