]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/process/detail/child_decl.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / process / detail / child_decl.hpp
CommitLineData
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/**
12 * \file boost/process/child.hpp
13 *
14 * Defines a child process class.
15 */
16
17#ifndef BOOST_PROCESS_CHILD_DECL_HPP
18#define BOOST_PROCESS_CHILD_DECL_HPP
19
20#include <boost/process/detail/config.hpp>
21#include <chrono>
22#include <memory>
23
24#include <boost/none.hpp>
25#include <atomic>
26
27#if defined(BOOST_POSIX_API)
28#include <boost/process/detail/posix/child_handle.hpp>
29#include <boost/process/detail/posix/terminate.hpp>
30#include <boost/process/detail/posix/wait_for_exit.hpp>
31#include <boost/process/detail/posix/is_running.hpp>
32#elif defined(BOOST_WINDOWS_API)
33#include <boost/process/detail/windows/child_handle.hpp>
34#include <boost/process/detail/windows/terminate.hpp>
35#include <boost/process/detail/windows/wait_for_exit.hpp>
36#include <boost/process/detail/windows/is_running.hpp>
37
38#endif
39namespace boost {
40
41namespace process {
42
43using ::boost::process::detail::api::pid_t;
44
45class child
46{
47 ::boost::process::detail::api::child_handle _child_handle;
48 std::shared_ptr<std::atomic<int>> _exit_status = std::make_shared<std::atomic<int>>(::boost::process::detail::api::still_active);
49 bool _attached = true;
50 bool _terminated = false;
51
52 bool _exited()
53 {
54 return _terminated || !::boost::process::detail::api::is_running(_exit_status->load());
55 };
56public:
57 typedef ::boost::process::detail::api::child_handle child_handle;
58 typedef child_handle::process_handle_t native_handle_t;
59 explicit child(child_handle &&ch, std::shared_ptr<std::atomic<int>> &ptr) : _child_handle(std::move(ch)), _exit_status(ptr) {}
60 explicit child(child_handle &&ch, const std::shared_ptr<std::atomic<int>> &ptr) : _child_handle(std::move(ch)), _exit_status(ptr) {}
61 explicit child(child_handle &&ch) : _child_handle(std::move(ch)) {}
62
1e59de90 63 explicit child(pid_t pid) : _child_handle(pid), _attached(false) {};
b32b8144
FG
64 child(const child&) = delete;
65 child(child && lhs) noexcept
66 : _child_handle(std::move(lhs._child_handle)),
67 _exit_status(std::move(lhs._exit_status)),
68 _attached (lhs._attached),
69 _terminated (lhs._terminated)
70 {
71 lhs._attached = false;
72 }
73
74 template<typename ...Args>
75 explicit child(Args&&...args);
20effc67 76 child() { } // Must be kept non defaulted for MSVC 14.1 & 14.2 #113
b32b8144
FG
77 child& operator=(const child&) = delete;
78 child& operator=(child && lhs)
79 {
80 _child_handle= std::move(lhs._child_handle);
81 _exit_status = std::move(lhs._exit_status);
82 _attached = lhs._attached;
83 _terminated = lhs._terminated;
84 lhs._attached = false;
85 return *this;
86 };
87
88 void detach() {_attached = false; }
89 void join() {wait();}
90 bool joinable() { return _attached;}
91
92 ~child()
93 {
94 std::error_code ec;
95 if (_attached && !_exited() && running(ec))
96 terminate(ec);
97 }
98 native_handle_t native_handle() const { return _child_handle.process_handle(); }
99
100
101 int exit_code() const {return ::boost::process::detail::api::eval_exit_status(_exit_status->load());}
102 pid_t id() const {return _child_handle.id(); }
103
92f5a8d4
TL
104 int native_exit_code() const {return _exit_status->load();}
105
b32b8144
FG
106 bool running()
107 {
11fdf7f2
TL
108 std::error_code ec;
109 bool b = running(ec);
110 boost::process::detail::throw_error(ec, "running error");
111 return b;
b32b8144
FG
112 }
113
114 void terminate()
115 {
11fdf7f2
TL
116 std::error_code ec;
117 terminate(ec);
118 boost::process::detail::throw_error(ec, "terminate error");
b32b8144
FG
119 }
120
121 void wait()
122 {
11fdf7f2
TL
123 std::error_code ec;
124 wait(ec);
125 boost::process::detail::throw_error(ec, "wait error");
b32b8144
FG
126 }
127
128 template< class Rep, class Period >
11fdf7f2 129 bool wait_for (const std::chrono::duration<Rep, Period>& rel_time)
b32b8144 130 {
11fdf7f2
TL
131 std::error_code ec;
132 bool b = wait_for(rel_time, ec);
133 boost::process::detail::throw_error(ec, "wait_for error");
134 return b;
b32b8144
FG
135 }
136
137 template< class Clock, class Duration >
138 bool wait_until(const std::chrono::time_point<Clock, Duration>& timeout_time )
139 {
11fdf7f2
TL
140 std::error_code ec;
141 bool b = wait_until(timeout_time, ec);
142 boost::process::detail::throw_error(ec, "wait_until error");
143 return b;
b32b8144
FG
144 }
145
146 bool running(std::error_code & ec) noexcept
147 {
92f5a8d4
TL
148 ec.clear();
149 if (valid() && !_exited() && !ec)
b32b8144 150 {
11fdf7f2
TL
151 int exit_code = 0;
152 auto res = boost::process::detail::api::is_running(_child_handle, exit_code, ec);
92f5a8d4 153 if (!ec && !res && !_exited())
11fdf7f2 154 _exit_status->store(exit_code);
b32b8144
FG
155
156 return res;
157 }
158 return false;
159 }
160
161 void terminate(std::error_code & ec) noexcept
162 {
92f5a8d4 163 if (valid() && running(ec) && !ec)
b32b8144
FG
164 boost::process::detail::api::terminate(_child_handle, ec);
165
92f5a8d4
TL
166 if (!ec)
167 _terminated = true;
b32b8144
FG
168 }
169
170 void wait(std::error_code & ec) noexcept
171 {
172 if (!_exited() && valid())
173 {
174 int exit_code = 0;
175 boost::process::detail::api::wait(_child_handle, exit_code, ec);
92f5a8d4
TL
176 if (!ec)
177 _exit_status->store(exit_code);
b32b8144
FG
178 }
179 }
180
181 template< class Rep, class Period >
11fdf7f2 182 bool wait_for (const std::chrono::duration<Rep, Period>& rel_time, std::error_code & ec) noexcept
b32b8144 183 {
11fdf7f2 184 return wait_until(std::chrono::steady_clock::now() + rel_time, ec);
b32b8144
FG
185 }
186
187 template< class Clock, class Duration >
188 bool wait_until(const std::chrono::time_point<Clock, Duration>& timeout_time, std::error_code & ec) noexcept
189 {
190 if (!_exited())
191 {
192 int exit_code = 0;
193 auto b = boost::process::detail::api::wait_until(_child_handle, exit_code, timeout_time, ec);
92f5a8d4 194 if (!b || ec)
b32b8144
FG
195 return false;
196 _exit_status->store(exit_code);
197 }
198 return true;
199 }
200
201
202 bool valid() const
203 {
204 return _child_handle.valid();
205 }
206 operator bool() const {return valid();}
207
208 bool in_group() const
209 {
210 return _child_handle.in_group();
211 }
212 bool in_group(std::error_code &ec) const noexcept
213 {
214 return _child_handle.in_group(ec);
215 }
216};
217
218
219
220}}
221#endif
222