diff --git a/include/boost/process/v2/detail/process_handle_fd.hpp b/include/boost/process/v2/detail/process_handle_fd.hpp index 9a036335..8af291d9 100644 --- a/include/boost/process/v2/detail/process_handle_fd.hpp +++ b/include/boost/process/v2/detail/process_handle_fd.hpp @@ -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) diff --git a/include/boost/process/v2/detail/process_handle_fd_or_signal.hpp b/include/boost/process/v2/detail/process_handle_fd_or_signal.hpp index 5c241676..73c0e2be 100644 --- a/include/boost/process/v2/detail/process_handle_fd_or_signal.hpp +++ b/include/boost/process/v2/detail/process_handle_fd_or_signal.hpp @@ -18,19 +18,27 @@ #if defined(BOOST_PROCESS_V2_STANDALONE) #include +#include +#include #include #include #include #include -#include +#if !defined(BOOST_PROCESS_V2_DISABLE_SIGNALSET) +#include +#endif #else #include +#include +#include #include #include #include #include +#if !defined(BOOST_PROCESS_V2_DISABLE_SIGNALSET) #include #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 @@ -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 descriptor_; +#if !defined(BOOST_PROCESS_V2_DISABLE_SIGNALSET) net::basic_signal_set signal_set_{descriptor_.get_executor(), SIGCHLD}; - +#else + int signal_set_; +#endif struct async_wait_op_ { net::posix::basic_descriptor &descriptor; +#if !defined(BOOST_PROCESS_V2_DISABLE_SIGNALSET) net::basic_signal_set &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::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 + void operator()(Self &&self, native_exit_code_type code, error_code ec) + { + self.complete(ec, code); } }; public: diff --git a/include/boost/process/v2/detail/process_handle_signal.hpp b/include/boost/process/v2/detail/process_handle_signal.hpp index 6cf5ec89..5272a847 100644 --- a/include/boost/process/v2/detail/process_handle_signal.hpp +++ b/include/boost/process/v2/detail/process_handle_signal.hpp @@ -17,17 +17,25 @@ #if defined(BOOST_PROCESS_V2_STANDALONE) #include +#include +#include #include #include #include +#if !defined(BOOST_PROCESS_V2_DISABLE_SIGNALSET) #include +#endif #else #include +#include +#include #include #include #include +#if !defined(BOOST_PROCESS_V2_DISABLE_SIGNALSET) #include #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; 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 friend struct basic_process_handle_signal; pid_type pid_ = -1; +#if !defined(BOOST_PROCESS_V2_DISABLE_SIGNALSET) net::basic_signal_set 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 &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::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 + 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 + void operator()(Self &&self, native_exit_code_type code, error_code ec) + { + self.complete(ec, code); } }; public: diff --git a/include/boost/process/v2/process_handle.hpp b/include/boost/process/v2/process_handle.hpp index 437859c1..626646b0 100644 --- a/include/boost/process/v2/process_handle.hpp +++ b/include/boost/process/v2/process_handle.hpp @@ -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`. diff --git a/test/v2/ext.cpp b/test/v2/ext.cpp index 0ed55c9c..42281e96 100644 --- a/test/v2/ext.cpp +++ b/test/v2/ext.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include BOOST_AUTO_TEST_SUITE(ext) diff --git a/test/v2/pid.cpp b/test/v2/pid.cpp index d66de189..0d013665 100644 --- a/test/v2/pid.cpp +++ b/test/v2/pid.cpp @@ -7,6 +7,8 @@ #include #include +#include + #include #include diff --git a/test/v2/process.cpp b/test/v2/process.cpp index b2b71dfd..d976cd35 100644 --- a/test/v2/process.cpp +++ b/test/v2/process.cpp @@ -655,7 +655,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();