Skip to content

Commit

Permalink
sighchld service & test fixes.
Browse files Browse the repository at this point in the history
  • Loading branch information
klemens-morgenstern committed Feb 17, 2023
1 parent eae10da commit 8639dc2
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 44 deletions.
85 changes: 44 additions & 41 deletions include/boost/process/detail/posix/sigchld_service.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@
#ifndef BOOST_PROCESS_DETAIL_POSIX_SIGCHLD_SERVICE_HPP_
#define BOOST_PROCESS_DETAIL_POSIX_SIGCHLD_SERVICE_HPP_

#include <boost/asio/bind_executor.hpp>
#include <boost/asio/dispatch.hpp>
#include <boost/asio/post.hpp>
#include <boost/asio/consign.hpp>
#include <boost/asio/append.hpp>
#include <boost/asio/signal_set.hpp>
#include <boost/asio/strand.hpp>
#include <boost/optional.hpp>
Expand All @@ -26,6 +29,43 @@ class sigchld_service : public boost::asio::detail::service_base<sigchld_service

std::list<std::pair<::pid_t, std::function<void(int, std::error_code)>>> _receivers;
inline void _handle_signal(const boost::system::error_code & ec);

struct initiate_async_wait_op
{
sigchld_service * self;
template<typename Initiation>
void operator()(Initiation && init, ::pid_t pid)
{
// check if the child actually is running first
int status;
auto pid_res = ::waitpid(pid, &status, WNOHANG);
if (pid_res < 0)
{
auto ec = get_last_error();
boost::asio::post(
self->_strand,
asio::append(std::forward<Initiation>(init), pid_res, ec));
}
else if ((pid_res == pid) && (WIFEXITED(status) || WIFSIGNALED(status)))
boost::asio::post(
self->_strand,
boost::asio::append(std::forward<Initiation>(init), status, std::error_code{}));
else //still running
{
sigchld_service * self_ = self;
if (self->_receivers.empty())
self->_signal_set.async_wait(
boost::asio::bind_executor(
self->_strand,
[self_](const boost::system::error_code &ec, int)
{
self_->_handle_signal(ec);
}));
self->_receivers.emplace_back(pid, init);
}
}
};

public:
sigchld_service(boost::asio::io_context & io_context)
: boost::asio::detail::service_base<sigchld_service>(io_context)
Expand All @@ -37,47 +77,10 @@ class sigchld_service : public boost::asio::detail::service_base<sigchld_service
void (int, std::error_code))
async_wait(::pid_t pid, SignalHandler && handler)
{
boost::asio::async_completion<
SignalHandler, void(boost::system::error_code)> init{handler};

auto & h = init.completion_handler;
boost::asio::dispatch(
_strand,
[this, pid, h]
{
//check if the child actually is running first
int status;
auto pid_res = ::waitpid(pid, &status, WNOHANG);
if (pid_res < 0)
{
auto ec = get_last_error();
boost::asio::post(
_strand,
[pid_res, ec, h]
{
h(pid_res, ec);
});
}
else if ((pid_res == pid) && (WIFEXITED(status) || WIFSIGNALED(status)))
boost::asio::post(
_strand,
[status, h]
{
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();
return boost::asio::async_initiate<
SignalHandler,
void(int, std::error_code)>(
initiate_async_wait_op{this}, handler, pid);
}
void shutdown() override
{
Expand Down
2 changes: 1 addition & 1 deletion test/async_pipe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ BOOST_AUTO_TEST_CASE(multithreaded_async_pipe)
asio::io_context ioc;

std::vector<std::thread> threads;
for (int i = 0; i < std::thread::hardware_concurrency(); i++)
for (auto i = 0u; i < std::thread::hardware_concurrency(); i++)
{
threads.emplace_back([&ioc]
{
Expand Down
2 changes: 1 addition & 1 deletion test/group_wait.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ BOOST_AUTO_TEST_CASE(wait_group_test, *boost::unit_test::timeout(5))
BOOST_CHECK_MESSAGE(!ec, ec.message());
BOOST_REQUIRE(c2.in_group(ec));
BOOST_CHECK_MESSAGE(!ec, ec.message());
g.wait();
g.wait(ec);

BOOST_CHECK(!c1.running());
BOOST_CHECK(!c2.running());
Expand Down
2 changes: 1 addition & 1 deletion test/v2/ext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ BOOST_AUTO_TEST_CASE(cmd_exe)
BOOST_CHECK_EQUAL(bp2::detail::conv_string<char>(ref.data(), ref.size()), pth);

BOOST_REQUIRE_EQUAL(cm.argc(), args.size() + 1);
for (auto i = 0; i < args.size(); i++)
for (auto i = 0u; i < args.size(); i++)
{
ref = cm.argv()[i + 1];

Expand Down

0 comments on commit 8639dc2

Please sign in to comment.