File indexing completed on 2025-01-18 09:50:08
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_PROCESS_WINDOWS_WAIT_FOR_EXIT_HPP
0012 #define BOOST_PROCESS_WINDOWS_WAIT_FOR_EXIT_HPP
0013
0014 #include <boost/process/detail/config.hpp>
0015 #include <system_error>
0016 #include <boost/winapi/synchronization.hpp>
0017 #include <boost/winapi/process.hpp>
0018 #include <boost/process/detail/windows/child_handle.hpp>
0019 #include <chrono>
0020
0021 namespace boost { namespace process { namespace detail { namespace windows {
0022
0023 inline void wait(child_handle &p, int & exit_code, std::error_code &ec) noexcept
0024 {
0025 ::boost::winapi::DWORD_ _exit_code = 1;
0026
0027 if (::boost::winapi::WaitForSingleObject(p.process_handle(),
0028 ::boost::winapi::infinite) == ::boost::winapi::wait_failed)
0029 ec = std::error_code(
0030 ::boost::winapi::GetLastError(),
0031 std::system_category());
0032 else if (!::boost::winapi::GetExitCodeProcess(p.process_handle(), &_exit_code))
0033 ec = std::error_code(
0034 ::boost::winapi::GetLastError(),
0035 std::system_category());
0036 else
0037 ec.clear();
0038
0039 ::boost::winapi::CloseHandle(p.proc_info.hProcess);
0040 p.proc_info.hProcess = ::boost::winapi::INVALID_HANDLE_VALUE_;
0041 exit_code = static_cast<int>(_exit_code);
0042 }
0043
0044 inline void wait(child_handle &p, int & exit_code)
0045 {
0046 std::error_code ec;
0047 wait(p, exit_code, ec);
0048 boost::process::detail::throw_error(ec, "wait error");
0049 }
0050
0051 template< class Clock, class Duration >
0052 inline bool wait_until(
0053 child_handle &p,
0054 int & exit_code,
0055 const std::chrono::time_point<Clock, Duration>& timeout_time,
0056 std::error_code &ec) noexcept
0057 {
0058 std::chrono::milliseconds ms =
0059 std::chrono::duration_cast<std::chrono::milliseconds>(
0060 timeout_time - Clock::now());
0061
0062 ::boost::winapi::DWORD_ wait_code;
0063 wait_code = ::boost::winapi::WaitForSingleObject(p.process_handle(),
0064 static_cast<::boost::winapi::DWORD_>(ms.count()));
0065
0066 if (wait_code == ::boost::winapi::wait_failed)
0067 ec = std::error_code(
0068 ::boost::winapi::GetLastError(),
0069 std::system_category());
0070 else if (wait_code == ::boost::winapi::wait_timeout)
0071 return false;
0072
0073 ::boost::winapi::DWORD_ _exit_code;
0074 if (!::boost::winapi::GetExitCodeProcess(p.process_handle(), &_exit_code))
0075 ec = std::error_code(
0076 ::boost::winapi::GetLastError(),
0077 std::system_category());
0078 else
0079 ec.clear();
0080
0081 exit_code = static_cast<int>(_exit_code);
0082 ::boost::winapi::CloseHandle(p.proc_info.hProcess);
0083 p.proc_info.hProcess = ::boost::winapi::INVALID_HANDLE_VALUE_;
0084 return true;
0085 }
0086
0087 template< class Clock, class Duration >
0088 inline bool wait_until(
0089 child_handle &p,
0090 int & exit_code,
0091 const std::chrono::time_point<Clock, Duration>& timeout_time)
0092 {
0093 std::error_code ec;
0094 bool b = wait_until(p, exit_code, timeout_time, ec);
0095 boost::process::detail::throw_error(ec, "wait_until error");
0096 return b;
0097 }
0098
0099 template< class Rep, class Period >
0100 inline bool wait_for(
0101 child_handle &p,
0102 int & exit_code,
0103 const std::chrono::duration<Rep, Period>& rel_time,
0104 std::error_code &ec) noexcept
0105 {
0106 return wait_until(p, exit_code, std::chrono::steady_clock::now() + rel_time, ec);
0107 }
0108
0109 template< class Rep, class Period >
0110 inline bool wait_for(
0111 child_handle &p,
0112 int & exit_code,
0113 const std::chrono::duration<Rep, Period>& rel_time)
0114 {
0115 std::error_code ec;
0116 bool b = wait_for(p, exit_code, rel_time, ec);
0117 boost::process::detail::throw_error(ec, "wait_for error");
0118 return b;
0119 }
0120
0121 }}}}
0122
0123 #endif