]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/process/detail/windows/wait_for_exit.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / process / detail / windows / wait_for_exit.hpp
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
23 inline void wait(child_handle &p, int & exit_code)
24 {
25 if (::boost::winapi::WaitForSingleObject(p.process_handle(),
26 ::boost::winapi::infinite) == ::boost::winapi::wait_failed)
27 throw_last_error("WaitForSingleObject() failed");
28
29 ::boost::winapi::DWORD_ _exit_code;
30 if (!::boost::winapi::GetExitCodeProcess(p.process_handle(), &_exit_code))
31 throw_last_error("GetExitCodeProcess() failed");
32
33 ::boost::winapi::CloseHandle(p.proc_info.hProcess);
34 p.proc_info.hProcess = ::boost::winapi::INVALID_HANDLE_VALUE_;
35 exit_code = static_cast<int>(_exit_code);
36 }
37
38 inline void wait(child_handle &p, int & exit_code, std::error_code &ec) noexcept
39 {
40 ::boost::winapi::DWORD_ _exit_code = 1;
41
42 if (::boost::winapi::WaitForSingleObject(p.process_handle(),
43 ::boost::winapi::infinite) == ::boost::winapi::wait_failed)
44 ec = std::error_code(
45 ::boost::winapi::GetLastError(),
46 std::system_category());
47 else if (!::boost::winapi::GetExitCodeProcess(p.process_handle(), &_exit_code))
48 ec = std::error_code(
49 ::boost::winapi::GetLastError(),
50 std::system_category());
51 else
52 ec.clear();
53
54 ::boost::winapi::CloseHandle(p.proc_info.hProcess);
55 p.proc_info.hProcess = ::boost::winapi::INVALID_HANDLE_VALUE_;
56 exit_code = static_cast<int>(_exit_code);
57 }
58
59
60 template< class Rep, class Period >
61 inline bool wait_for(
62 child_handle &p,
63 int & exit_code,
64 const std::chrono::duration<Rep, Period>& rel_time)
65 {
66
67 std::chrono::milliseconds ms = std::chrono::duration_cast<std::chrono::milliseconds>(rel_time);
68
69 ::boost::winapi::DWORD_ wait_code;
70 wait_code = ::boost::winapi::WaitForSingleObject(p.process_handle(),
71 static_cast<::boost::winapi::DWORD_>(ms.count()));
72 if (wait_code == ::boost::winapi::wait_failed)
73 throw_last_error("WaitForSingleObject() failed");
74 else if (wait_code == ::boost::winapi::wait_timeout)
75 return false; //
76
77 ::boost::winapi::DWORD_ _exit_code;
78 if (!::boost::winapi::GetExitCodeProcess(p.process_handle(), &_exit_code))
79 throw_last_error("GetExitCodeProcess() failed");
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;
85 }
86
87
88 template< class Rep, class Period >
89 inline bool wait_for(
90 child_handle &p,
91 int & exit_code,
92 const std::chrono::duration<Rep, Period>& rel_time,
93 std::error_code &ec) noexcept
94 {
95
96 std::chrono::milliseconds ms = std::chrono::duration_cast<std::chrono::milliseconds>(rel_time);
97
98
99 ::boost::winapi::DWORD_ wait_code;
100 wait_code = ::boost::winapi::WaitForSingleObject(p.process_handle(),
101 static_cast<::boost::winapi::DWORD_>(ms.count()));
102 if (wait_code == ::boost::winapi::wait_failed)
103 ec = std::error_code(
104 ::boost::winapi::GetLastError(),
105 std::system_category());
106 else if (wait_code == ::boost::winapi::wait_timeout)
107 return false; //
108
109 ::boost::winapi::DWORD_ _exit_code = 1;
110 if (!::boost::winapi::GetExitCodeProcess(p.process_handle(), &_exit_code))
111 {
112 ec = std::error_code(
113 ::boost::winapi::GetLastError(),
114 std::system_category());
115 return false;
116 }
117 else
118 ec.clear();
119
120 exit_code = static_cast<int>(_exit_code);
121 ::boost::winapi::CloseHandle(p.proc_info.hProcess);
122 p.proc_info.hProcess = ::boost::winapi::INVALID_HANDLE_VALUE_;
123 return true;
124 ;
125 }
126
127 template< class Clock, class Duration >
128 inline bool wait_until(
129 child_handle &p,
130 int & exit_code,
131 const std::chrono::time_point<Clock, Duration>& timeout_time)
132 {
133 std::chrono::milliseconds ms =
134 std::chrono::duration_cast<std::chrono::milliseconds>(
135 timeout_time - std::chrono::system_clock::now());
136
137 ::boost::winapi::DWORD_ wait_code;
138 wait_code = ::boost::winapi::WaitForSingleObject(p.process_handle(),
139 static_cast<::boost::winapi::DWORD_>(ms.count()));
140
141 if (wait_code == ::boost::winapi::wait_failed)
142 throw_last_error("WaitForSingleObject() failed");
143 else if (wait_code == ::boost::winapi::wait_timeout)
144 return false;
145
146 ::boost::winapi::DWORD_ _exit_code;
147 if (!::boost::winapi::GetExitCodeProcess(p.process_handle(), &_exit_code))
148 throw_last_error("GetExitCodeProcess() failed");
149
150 exit_code = static_cast<int>(_exit_code);
151 ::boost::winapi::CloseHandle(p.proc_info.hProcess);
152 p.proc_info.hProcess = ::boost::winapi::INVALID_HANDLE_VALUE_;
153 return true;
154 }
155
156
157 template< class Clock, class Duration >
158 inline bool wait_until(
159 child_handle &p,
160 int & exit_code,
161 const std::chrono::time_point<Clock, Duration>& timeout_time,
162 std::error_code &ec) noexcept
163 {
164 std::chrono::milliseconds ms =
165 std::chrono::duration_cast<std::chrono::milliseconds>(
166 timeout_time - std::chrono::system_clock::now());
167
168 ::boost::winapi::DWORD_ wait_code;
169 wait_code = ::boost::winapi::WaitForSingleObject(p.process_handle(),
170 static_cast<::boost::winapi::DWORD_>(ms.count()));
171
172 if (wait_code == ::boost::winapi::wait_failed)
173 ec = std::error_code(
174 ::boost::winapi::GetLastError(),
175 std::system_category());
176 else if (wait_code == ::boost::winapi::wait_timeout)
177 return false;
178
179 ::boost::winapi::DWORD_ _exit_code;
180 if (!::boost::winapi::GetExitCodeProcess(p.process_handle(), &_exit_code))
181 ec = std::error_code(
182 ::boost::winapi::GetLastError(),
183 std::system_category());
184 else
185 ec.clear();
186
187 exit_code = static_cast<int>(_exit_code);
188 ::boost::winapi::CloseHandle(p.proc_info.hProcess);
189 p.proc_info.hProcess = ::boost::winapi::INVALID_HANDLE_VALUE_;
190 return true;
191 ;
192 }
193
194
195 }}}}
196
197 #endif