]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/process/detail/windows/group_handle.hpp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / boost / process / detail / windows / group_handle.hpp
1 // Copyright (c) 2016 Klemens D. Morgenstern
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6 #ifndef BOOST_PROCESS_DETAIL_WINDOWS_GROUP_HPP_
7 #define BOOST_PROCESS_DETAIL_WINDOWS_GROUP_HPP_
8
9 #include <boost/process/detail/windows/handler.hpp>
10 #include <boost/winapi/jobs.hpp>
11 #include <boost/process/detail/windows/child_handle.hpp>
12 #include <boost/process/detail/windows/job_workaround.hpp>
13 #include <system_error>
14
15 namespace boost { namespace process { namespace detail { namespace windows {
16
17 inline bool break_away_enabled(::boost::winapi::HANDLE_ h)
18 {
19 workaround::JOBOBJECT_EXTENDED_LIMIT_INFORMATION_ info;
20
21 if (!workaround::query_information_job_object(
22 h,
23 workaround::JobObjectExtendedLimitInformation_,
24 static_cast<void*>(&info),
25 sizeof(info),
26 nullptr))
27 throw_last_error("QueryInformationJobObject() failed");
28
29 return (info.BasicLimitInformation.LimitFlags & workaround::JOB_OBJECT_LIMIT_BREAKAWAY_OK_) != 0;
30 }
31
32 inline void enable_break_away(::boost::winapi::HANDLE_ h)
33 {
34 workaround::JOBOBJECT_EXTENDED_LIMIT_INFORMATION_ info;
35
36 if (!workaround::query_information_job_object(
37 h,
38 workaround::JobObjectExtendedLimitInformation_,
39 static_cast<void*>(&info),
40 sizeof(info),
41 nullptr))
42 throw_last_error("QueryInformationJobObject() failed");
43
44 if ((info.BasicLimitInformation.LimitFlags & workaround::JOB_OBJECT_LIMIT_BREAKAWAY_OK_) != 0)
45 return;
46
47 info.BasicLimitInformation.LimitFlags |= workaround::JOB_OBJECT_LIMIT_BREAKAWAY_OK_;
48
49 if (!workaround::set_information_job_object(
50 h,
51 workaround::JobObjectExtendedLimitInformation_,
52 static_cast<void*>(&info),
53 sizeof(info)))
54 throw_last_error("SetInformationJobObject() failed");
55 }
56
57 inline void enable_break_away(::boost::winapi::HANDLE_ h, std::error_code & ec)
58 {
59 workaround::JOBOBJECT_EXTENDED_LIMIT_INFORMATION_ info;
60
61
62 if (!workaround::query_information_job_object(
63 h,
64 workaround::JobObjectExtendedLimitInformation_,
65 static_cast<void*>(&info),
66 sizeof(info),
67 nullptr))
68 {
69 ec = get_last_error();
70 return;
71 }
72
73 if ((info.BasicLimitInformation.LimitFlags & workaround::JOB_OBJECT_LIMIT_BREAKAWAY_OK_) != 0)
74 return;
75
76 info.BasicLimitInformation.LimitFlags |= workaround::JOB_OBJECT_LIMIT_BREAKAWAY_OK_;
77
78 if (!workaround::set_information_job_object(
79 h,
80 workaround::JobObjectExtendedLimitInformation_,
81 static_cast<void*>(&info),
82 sizeof(info)))
83 {
84 ec = get_last_error();
85 return;
86 }
87
88
89 }
90
91
92 struct group_handle
93 {
94 ::boost::winapi::HANDLE_ _job_object;
95
96 typedef ::boost::winapi::HANDLE_ handle_t;
97 handle_t handle() const { return _job_object; }
98
99 explicit group_handle(handle_t h) :
100 _job_object(h)
101 {
102 enable_break_away(_job_object);
103 }
104
105
106 group_handle() : group_handle(::boost::winapi::CreateJobObjectW(nullptr, nullptr))
107 {
108
109 }
110 ~group_handle()
111 {
112 ::boost::winapi::CloseHandle(_job_object);
113 }
114 group_handle(const group_handle & c) = delete;
115 group_handle(group_handle && c) : _job_object(c._job_object)
116 {
117 c._job_object = ::boost::winapi::invalid_handle_value;
118 }
119 group_handle &operator=(const group_handle & c) = delete;
120 group_handle &operator=(group_handle && c)
121 {
122
123 ::boost::winapi::CloseHandle(_job_object);
124 _job_object = c._job_object;
125 c._job_object = ::boost::winapi::invalid_handle_value;
126 return *this;
127 }
128
129 void add(handle_t proc)
130 {
131 if (!::boost::winapi::AssignProcessToJobObject(_job_object, proc))
132 throw_last_error();
133 }
134 void add(handle_t proc, std::error_code & ec) noexcept
135 {
136 if (!::boost::winapi::AssignProcessToJobObject(_job_object, proc))
137 ec = get_last_error();
138 }
139
140 bool has(handle_t proc)
141 {
142 ::boost::winapi::BOOL_ is;
143 if (!::boost::winapi::IsProcessInJob(proc, _job_object, &is))
144 throw_last_error();
145
146 return is!=0;
147 }
148 bool has(handle_t proc, std::error_code & ec) noexcept
149 {
150 ::boost::winapi::BOOL_ is;
151 if (!::boost::winapi::IsProcessInJob(proc, _job_object, &is))
152 ec = get_last_error();
153 return is!=0;
154 }
155
156 bool valid() const
157 {
158 return _job_object != nullptr;
159 }
160
161 };
162
163 inline void terminate(const group_handle &p)
164 {
165 if (!::boost::winapi::TerminateJobObject(p.handle(), EXIT_FAILURE))
166 boost::process::detail::throw_last_error("TerminateJobObject() failed");
167 }
168
169 inline void terminate(const group_handle &p, std::error_code &ec) noexcept
170 {
171 if (!::boost::winapi::TerminateJobObject(p.handle(), EXIT_FAILURE))
172 ec = boost::process::detail::get_last_error();
173 else
174 ec.clear();
175 }
176
177 inline bool in_group()
178 {
179 ::boost::winapi::BOOL_ res;
180 if (!::boost::winapi::IsProcessInJob(boost::winapi::GetCurrentProcess(), nullptr, &res))
181 throw_last_error("IsProcessInJob failed");
182
183 return res!=0;
184 }
185
186
187
188 }}}}
189
190
191 #endif /* BOOST_PROCESS_DETAIL_WINDOWS_GROUP_HPP_ */