]>
Commit | Line | Data |
---|---|---|
b32b8144 FG |
1 | // Copyright (c) 2006, 2007 Julio M. Merino Vidal |
2 | // Copyright (c) 2008 Ilya Sokolov, Boris Schaeling | |
3 | // Copyright (c) 2009 Boris Schaeling | |
4 | // Copyright (c) 2010 Felipe Tanus, Boris Schaeling | |
5 | // Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling | |
6 | // Copyright (c) 2016 Klemens D. Morgenstern | |
7 | // | |
8 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
9 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
10 | ||
11 | #ifndef BOOST_PROCESS_WINDOWS_WAIT_FOR_EXIT_HPP | |
12 | #define BOOST_PROCESS_WINDOWS_WAIT_FOR_EXIT_HPP | |
13 | ||
14 | #include <boost/process/detail/config.hpp> | |
15 | #include <system_error> | |
16 | #include <boost/winapi/synchronization.hpp> | |
17 | #include <boost/winapi/process.hpp> | |
18 | #include <boost/process/detail/windows/child_handle.hpp> | |
19 | #include <chrono> | |
20 | ||
21 | namespace boost { namespace process { namespace detail { namespace windows { | |
22 | ||
b32b8144 FG |
23 | inline void wait(child_handle &p, int & exit_code, std::error_code &ec) noexcept |
24 | { | |
25 | ::boost::winapi::DWORD_ _exit_code = 1; | |
26 | ||
27 | if (::boost::winapi::WaitForSingleObject(p.process_handle(), | |
28 | ::boost::winapi::infinite) == ::boost::winapi::wait_failed) | |
29 | ec = std::error_code( | |
30 | ::boost::winapi::GetLastError(), | |
31 | std::system_category()); | |
32 | else if (!::boost::winapi::GetExitCodeProcess(p.process_handle(), &_exit_code)) | |
33 | ec = std::error_code( | |
34 | ::boost::winapi::GetLastError(), | |
35 | std::system_category()); | |
36 | else | |
37 | ec.clear(); | |
38 | ||
39 | ::boost::winapi::CloseHandle(p.proc_info.hProcess); | |
40 | p.proc_info.hProcess = ::boost::winapi::INVALID_HANDLE_VALUE_; | |
41 | exit_code = static_cast<int>(_exit_code); | |
42 | } | |
43 | ||
11fdf7f2 | 44 | inline void wait(child_handle &p, int & exit_code) |
b32b8144 | 45 | { |
11fdf7f2 TL |
46 | std::error_code ec; |
47 | wait(p, exit_code, ec); | |
48 | boost::process::detail::throw_error(ec, "wait error"); | |
b32b8144 FG |
49 | } |
50 | ||
11fdf7f2 TL |
51 | template< class Clock, class Duration > |
52 | inline bool wait_until( | |
b32b8144 FG |
53 | child_handle &p, |
54 | int & exit_code, | |
11fdf7f2 | 55 | const std::chrono::time_point<Clock, Duration>& timeout_time, |
b32b8144 FG |
56 | std::error_code &ec) noexcept |
57 | { | |
11fdf7f2 TL |
58 | std::chrono::milliseconds ms = |
59 | std::chrono::duration_cast<std::chrono::milliseconds>( | |
60 | timeout_time - Clock::now()); | |
b32b8144 FG |
61 | |
62 | ::boost::winapi::DWORD_ wait_code; | |
63 | wait_code = ::boost::winapi::WaitForSingleObject(p.process_handle(), | |
11fdf7f2 TL |
64 | static_cast<::boost::winapi::DWORD_>(ms.count())); |
65 | ||
b32b8144 FG |
66 | if (wait_code == ::boost::winapi::wait_failed) |
67 | ec = std::error_code( | |
68 | ::boost::winapi::GetLastError(), | |
69 | std::system_category()); | |
70 | else if (wait_code == ::boost::winapi::wait_timeout) | |
11fdf7f2 | 71 | return false; |
b32b8144 | 72 | |
11fdf7f2 | 73 | ::boost::winapi::DWORD_ _exit_code; |
b32b8144 | 74 | if (!::boost::winapi::GetExitCodeProcess(p.process_handle(), &_exit_code)) |
b32b8144 FG |
75 | ec = std::error_code( |
76 | ::boost::winapi::GetLastError(), | |
77 | std::system_category()); | |
b32b8144 FG |
78 | else |
79 | ec.clear(); | |
80 | ||
81 | exit_code = static_cast<int>(_exit_code); | |
82 | ::boost::winapi::CloseHandle(p.proc_info.hProcess); | |
83 | p.proc_info.hProcess = ::boost::winapi::INVALID_HANDLE_VALUE_; | |
84 | return true; | |
b32b8144 FG |
85 | } |
86 | ||
87 | template< class Clock, class Duration > | |
88 | inline bool wait_until( | |
89 | child_handle &p, | |
90 | int & exit_code, | |
91 | const std::chrono::time_point<Clock, Duration>& timeout_time) | |
92 | { | |
11fdf7f2 TL |
93 | std::error_code ec; |
94 | bool b = wait_until(p, exit_code, timeout_time, ec); | |
95 | boost::process::detail::throw_error(ec, "wait_until error"); | |
96 | return b; | |
b32b8144 FG |
97 | } |
98 | ||
11fdf7f2 TL |
99 | template< class Rep, class Period > |
100 | inline bool wait_for( | |
b32b8144 FG |
101 | child_handle &p, |
102 | int & exit_code, | |
11fdf7f2 | 103 | const std::chrono::duration<Rep, Period>& rel_time, |
b32b8144 FG |
104 | std::error_code &ec) noexcept |
105 | { | |
11fdf7f2 | 106 | return wait_until(p, exit_code, std::chrono::steady_clock::now() + rel_time, ec); |
b32b8144 FG |
107 | } |
108 | ||
11fdf7f2 TL |
109 | template< class Rep, class Period > |
110 | inline bool wait_for( | |
111 | child_handle &p, | |
112 | int & exit_code, | |
113 | const std::chrono::duration<Rep, Period>& rel_time) | |
114 | { | |
115 | std::error_code ec; | |
116 | bool b = wait_for(p, exit_code, rel_time, ec); | |
117 | boost::process::detail::throw_error(ec, "wait_for error"); | |
118 | return b; | |
119 | } | |
b32b8144 FG |
120 | |
121 | }}}} | |
122 | ||
123 | #endif |