File indexing completed on 2025-01-18 09:50:06
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_PROCESS_DETAIL_POSIX_WAIT_GROUP_HPP
0011 #define BOOST_PROCESS_DETAIL_POSIX_WAIT_GROUP_HPP
0012
0013 #include <boost/process/detail/config.hpp>
0014 #include <boost/process/detail/posix/group_handle.hpp>
0015 #include <chrono>
0016 #include <system_error>
0017 #include <sys/types.h>
0018 #include <sys/wait.h>
0019 #include <unistd.h>
0020
0021 namespace boost { namespace process { namespace detail { namespace posix {
0022
0023 inline void wait(const group_handle &p, std::error_code &ec) noexcept
0024 {
0025 pid_t ret;
0026 siginfo_t status;
0027
0028 do
0029 {
0030 ret = ::waitpid(-p.grp, &status.si_status, 0);
0031 if (ret == -1)
0032 {
0033 ec = get_last_error();
0034 return;
0035 }
0036
0037
0038 ret = ::waitid(P_PGID, p.grp, &status, WEXITED | WNOHANG);
0039 }
0040 while ((ret != -1) || (errno != ECHILD));
0041
0042 if (errno != ECHILD)
0043 ec = boost::process::detail::get_last_error();
0044 else
0045 ec.clear();
0046 }
0047
0048 inline void wait(const group_handle &p) noexcept
0049 {
0050 std::error_code ec;
0051 wait(p, ec);
0052 boost::process::detail::throw_error(ec, "waitpid(2) failed in wait");
0053 }
0054
0055 template< class Clock, class Duration >
0056 inline bool wait_until(
0057 const group_handle &p,
0058 const std::chrono::time_point<Clock, Duration>& time_out,
0059 std::error_code & ec) noexcept
0060 {
0061
0062 ::siginfo_t siginfo;
0063
0064 bool timed_out = false;
0065 int ret;
0066
0067 ::timespec sleep_interval;
0068 sleep_interval.tv_sec = 0;
0069 sleep_interval.tv_nsec = 100000000;
0070
0071
0072 while (!(timed_out = (Clock::now() > time_out)))
0073 {
0074 ret = ::waitid(P_PGID, p.grp, &siginfo, WEXITED | WSTOPPED | WNOHANG);
0075 if (ret == -1)
0076 {
0077 if ((errno == ECHILD) || (errno == ESRCH))
0078 {
0079 ec.clear();
0080 return true;
0081 }
0082 ec = boost::process::detail::get_last_error();
0083 return false;
0084 }
0085
0086 ::nanosleep(&sleep_interval, nullptr);
0087 }
0088 return !timed_out;
0089 }
0090
0091 template< class Clock, class Duration >
0092 inline bool wait_until(
0093 const group_handle &p,
0094 const std::chrono::time_point<Clock, Duration>& time_out) noexcept
0095 {
0096 std::error_code ec;
0097 bool b = wait_until(p, time_out, ec);
0098 boost::process::detail::throw_error(ec, "waitpid(2) failed in wait_until");
0099 return b;
0100 }
0101
0102 template< class Rep, class Period >
0103 inline bool wait_for(
0104 const group_handle &p,
0105 const std::chrono::duration<Rep, Period>& rel_time,
0106 std::error_code & ec) noexcept
0107 {
0108 return wait_until(p, std::chrono::steady_clock::now() + rel_time, ec);
0109 }
0110
0111 template< class Rep, class Period >
0112 inline bool wait_for(
0113 const group_handle &p,
0114 const std::chrono::duration<Rep, Period>& rel_time) noexcept
0115 {
0116 std::error_code ec;
0117 bool b = wait_for(p, rel_time, ec);
0118 boost::process::detail::throw_error(ec, "waitpid(2) failed in wait_for");
0119 return b;
0120 }
0121
0122 }}}}
0123
0124 #endif