2
0
mirror of https://github.com/boostorg/process.git synced 2026-01-19 04:22:15 +00:00

added BOOST_PROCESS_V2_DISABLE_SIGNALSET option

This commit is contained in:
Klemens Morgenstern
2024-12-20 13:16:06 +08:00
parent 7e712985c1
commit 06595a2070
7 changed files with 108 additions and 51 deletions

View File

@@ -255,7 +255,7 @@ struct basic_process_handle_fd
ec.clear();
exit_code = code;
}
return false;
return false;
}
bool running(native_exit_code_type &exit_code)

View File

@@ -18,19 +18,27 @@
#if defined(BOOST_PROCESS_V2_STANDALONE)
#include <asio/any_io_executor.hpp>
#include <asio/append.hpp>
#include <asio/associated_immediate_executor.hpp>
#include <asio/compose.hpp>
#include <asio/dispatch.hpp>
#include <asio/posix/basic_stream_descriptor.hpp>
#include <asio/post.hpp>
#include <asio/windows/signal_set.hpp>
#if !defined(BOOST_PROCESS_V2_DISABLE_SIGNALSET)
#include <asio/signal_set.hpp>
#endif
#else
#include <boost/asio/any_io_executor.hpp>
#include <boost/asio/append.hpp>
#include <boost/asio/associated_immediate_executor.hpp>
#include <boost/asio/compose.hpp>
#include <boost/asio/dispatch.hpp>
#include <boost/asio/posix/basic_stream_descriptor.hpp>
#include <boost/asio/post.hpp>
#if !defined(BOOST_PROCESS_V2_DISABLE_SIGNALSET)
#include <boost/asio/signal_set.hpp>
#endif
#endif
BOOST_PROCESS_V2_BEGIN_NAMESPACE
@@ -45,7 +53,7 @@ struct basic_process_handle_fd_or_signal
typedef Executor executor_type;
executor_type get_executor()
{ return signal_set_.get_executor(); }
{ return descriptor_.get_executor(); }
/// Rebinds the process_handle to another executor.
template<typename Executor1>
@@ -277,14 +285,13 @@ struct basic_process_handle_fd_or_signal
int res = ::waitpid(pid_, &code, WNOHANG);
if (res == -1)
ec = get_last_error();
else
ec.clear();
if (process_is_running(res))
else if (res == 0)
return true;
else
{
ec.clear();
exit_code = code;
}
return false;
}
@@ -311,12 +318,19 @@ struct basic_process_handle_fd_or_signal
struct basic_process_handle_fd_or_signal;
pid_type pid_ = -1;
net::posix::basic_stream_descriptor<Executor> descriptor_;
#if !defined(BOOST_PROCESS_V2_DISABLE_SIGNALSET)
net::basic_signal_set<Executor> signal_set_{descriptor_.get_executor(), SIGCHLD};
#else
int signal_set_;
#endif
struct async_wait_op_
{
net::posix::basic_descriptor<Executor> &descriptor;
#if !defined(BOOST_PROCESS_V2_DISABLE_SIGNALSET)
net::basic_signal_set<Executor> &handle;
#else
int dummy;
#endif
pid_type pid_;
bool needs_post = true;
@@ -343,35 +357,41 @@ struct basic_process_handle_fd_or_signal
if (!ec && (wait_res == 0))
{
needs_post = false;
if (descriptor.is_open())
descriptor.async_wait(
net::posix::descriptor_base::wait_read,
std::move(self));
{
needs_post = false;
descriptor.async_wait(
net::posix::descriptor_base::wait_read,
std::move(self));
return;
}
else
handle.async_wait(std::move(self));
return;
{
#if !defined(BOOST_PROCESS_V2_DISABLE_SIGNALSET)
needs_post = false;
handle.async_wait(std::move(self));
return;
#else
BOOST_PROCESS_V2_ASSIGN_EC(ec, net::error::operation_not_supported);
#endif
}
}
struct completer
{
error_code ec;
native_exit_code_type code;
typename std::decay<Self>::type self;
void operator()()
{
self.complete(ec, code);
}
};
const auto exec = self.get_executor();
completer cpl{ec, exit_code, std::move(self)};
if (needs_post)
net::post(exec, std::move(cpl));
{
auto exec = net::get_associated_immediate_executor(self, descriptor.get_executor());
net::dispatch(exec, net::append(std::move(self), exit_code, ec));
}
else
net::dispatch(exec, std::move(cpl));
{
auto exec = net::get_associated_executor(self);
net::dispatch(exec, net::append(std::move(self), exit_code, ec));
}
}
template<typename Self>
void operator()(Self &&self, native_exit_code_type code, error_code ec)
{
self.complete(ec, code);
}
};
public:

View File

@@ -17,17 +17,25 @@
#if defined(BOOST_PROCESS_V2_STANDALONE)
#include <asio/any_io_executor.hpp>
#include <asio/append.hpp>
#include <asio/associated_immediate_executor.hpp>
#include <asio/compose.hpp>
#include <asio/dispatch.hpp>
#include <asio/post.hpp>
#if !defined(BOOST_PROCESS_V2_DISABLE_SIGNALSET)
#include <asio/signal_set.hpp>
#endif
#else
#include <boost/asio/any_io_executor.hpp>
#include <boost/asio/append.hpp>
#include <boost/asio/associated_immediate_executor.hpp>
#include <boost/asio/compose.hpp>
#include <boost/asio/dispatch.hpp>
#include <boost/asio/post.hpp>
#if !defined(BOOST_PROCESS_V2_DISABLE_SIGNALSET)
#include <boost/asio/signal_set.hpp>
#endif
#endif
BOOST_PROCESS_V2_BEGIN_NAMESPACE
@@ -86,9 +94,14 @@ struct basic_process_handle_signal
basic_process_handle_signal& operator=(basic_process_handle_signal && handle)
{
pid_ = handle.id();
#if !defined(BOOST_PROCESS_V2_DISABLE_SIGNALSET)
signal_set_.~basic_signal_set();
using ss = net::basic_signal_set<Executor>;
new (&signal_set_) ss(handle.get_executor(), SIGCHLD);
#else
signal_set_.executor = handle.signal_set_.executor;
#endif
handle.pid_ = -1;
return *this;
}
@@ -244,11 +257,13 @@ struct basic_process_handle_signal
int res = ::waitpid(pid_, &code, WNOHANG);
if (res == -1)
ec = get_last_error();
if (res == 0)
else if (res == 0)
return true;
else
{
ec.clear();
exit_code = code;
}
return false;
}
@@ -273,10 +288,24 @@ struct basic_process_handle_signal
template<typename>
friend struct basic_process_handle_signal;
pid_type pid_ = -1;
#if !defined(BOOST_PROCESS_V2_DISABLE_SIGNALSET)
net::basic_signal_set<Executor> signal_set_;
#else
struct signal_set_dummy_
{
signal_set_dummy_(signal_set_dummy_ &&) = default;
signal_set_dummy_(const signal_set_dummy_ &) = default;
Executor executor;
using executor_type = Executor;
executor_type get_executor() {return executor;}
signal_set_dummy_(Executor executor, int) : executor(std::move(executor)) {}
};
signal_set_dummy_ signal_set_;
#endif
struct async_wait_op_
{
#if !defined(BOOST_PROCESS_V2_DISABLE_SIGNALSET)
net::basic_signal_set<Executor> &handle;
pid_type pid_;
@@ -315,20 +344,25 @@ struct basic_process_handle_signal
return;
}
struct completer
{
error_code ec;
native_exit_code_type code;
typename std::decay<Self>::type self;
void operator()()
{
self.complete(ec, code);
}
};
const auto exec = self.get_executor();
net::dispatch(exec, completer{ec, exit_code, std::move(self)});
net::dispatch(exec, net::append(std::move(self), exit_code, ec));
}
#else
signal_set_dummy_ dummy_;
pid_t pid;
template<typename Self>
void operator()(Self &&self)
{
auto exec = net::get_associated_immediate_executor(self, dummy_.get_executor());
error_code ec;
BOOST_PROCESS_V2_ASSIGN_EC(ec, net::error::operation_not_supported);
net::dispatch(exec, net::append(std::move(self), native_exit_code_type(), ec));
}
#endif
template<typename Self>
void operator()(Self &&self, native_exit_code_type code, error_code ec)
{
self.complete(ec, code);
}
};
public:

View File

@@ -107,9 +107,9 @@ struct basic_process_handle
void request_exit()
/// Unconditionally terminates the process and stores the exit code in exit_status.
void terminate(native_exit_code_type &exit_status, error_code &ec);\
void terminate(native_exit_code_type &exit_status, error_code &ec);
/// Throwing @overload void terminate(native_exit_code_type &exit_code, error_code & ec)
void terminate(native_exit_code_type &exit_status);/
void terminate(native_exit_code_type &exit_status);
/// Checks if the current process is running.
/**If it has already completed, it assigns the exit code to `exit_code`.

View File

@@ -11,6 +11,7 @@
#include <boost/process/v2/pid.hpp>
#include <boost/process/v2/process.hpp>
#include <boost/process/v2/start_dir.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_SUITE(ext)

View File

@@ -7,6 +7,8 @@
#include <boost/process/v2/pid.hpp>
#include <boost/process/v2/process.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/test/unit_test.hpp>
#include <algorithm>

View File

@@ -725,7 +725,7 @@ BOOST_AUTO_TEST_CASE(async_cancel_wait)
proc.async_wait(asio::cancel_after(std::chrono::milliseconds(100),
[&](boost::system::error_code ec, int)
{
BOOST_CHECK(ec == asio::error::operation_aborted);
BOOST_CHECK_EQUAL(ec, asio::error::operation_aborted);
BOOST_CHECK(proc.running());
if (proc.running())
proc.terminate();