• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_JOB_WORKAROUND_HPP_
7 #define BOOST_PROCESS_DETAIL_WINDOWS_JOB_WORKAROUND_HPP_
8 
9 #include <boost/winapi/config.hpp>
10 #include <boost/winapi/basic_types.hpp>
11 #include <boost/winapi/dll.hpp>
12 #include <boost/winapi/overlapped.hpp>
13 
14 #if defined( BOOST_USE_WINDOWS_H )
15 #include <windows.h>
16 #else
17 extern "C"
18 {
19 BOOST_SYMBOL_IMPORT ::boost::winapi::HANDLE_ BOOST_WINAPI_WINAPI_CC CreateIoCompletionPort(
20         ::boost::winapi::HANDLE_    FileHandle,
21         ::boost::winapi::HANDLE_    ExistingCompletionPort,
22         ::boost::winapi::ULONG_PTR_ CompletionKey,
23         ::boost::winapi::DWORD_     NumberOfConcurrentThreads
24 );
25 
26 BOOST_SYMBOL_IMPORT ::boost::winapi::BOOL_ BOOST_WINAPI_WINAPI_CC GetQueuedCompletionStatus(
27         ::boost::winapi::HANDLE_       CompletionPort,
28         ::boost::winapi::LPDWORD_      lpNumberOfBytes,
29         ::boost::winapi::ULONG_PTR_    *lpCompletionKey,
30         _OVERLAPPED **lpOverlapped,
31         ::boost::winapi::DWORD_        dwMilliseconds
32 );
33 
34 }
35 #endif
36 namespace boost { namespace process { namespace detail { namespace windows { namespace workaround {
37 
38 extern "C"
39 {
40 
41 struct JOBOBJECT_ASSOCIATE_COMPLETION_PORT_
42 {
43     ::boost::winapi::PVOID_  CompletionKey;
44     ::boost::winapi::HANDLE_ CompletionPort;
45 };
46 
47 constexpr static int JOB_OBJECT_MSG_END_OF_JOB_TIME_          = 1;
48 constexpr static int JOB_OBJECT_MSG_END_OF_PROCESS_TIME_      = 2;
49 constexpr static int JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT_     = 3;
50 constexpr static int JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO_      = 4;
51 constexpr static int JOB_OBJECT_MSG_NEW_PROCESS_              = 6;
52 constexpr static int JOB_OBJECT_MSG_EXIT_PROCESS_             = 7;
53 constexpr static int JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS_    = 8;
54 constexpr static int JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT_     = 9;
55 constexpr static int JOB_OBJECT_MSG_JOB_MEMORY_LIMIT_         = 10;
56 constexpr static int JOB_OBJECT_MSG_NOTIFICATION_LIMIT_       = 11;
57 constexpr static int JOB_OBJECT_MSG_JOB_CYCLE_TIME_LIMIT_     = 12;
58 constexpr static int JOB_OBJECT_MSG_SILO_TERMINATED_          = 13;
59 
60 }
61 
get_queued_completion_status(::boost::winapi::HANDLE_ CompletionPort,::boost::winapi::LPDWORD_ lpNumberOfBytes,::boost::winapi::ULONG_PTR_ * lpCompletionKey,::boost::winapi::LPOVERLAPPED_ * lpOverlapped,::boost::winapi::DWORD_ dwMilliseconds)62 BOOST_FORCEINLINE ::boost::winapi::BOOL_  get_queued_completion_status(
63         ::boost::winapi::HANDLE_       CompletionPort,
64         ::boost::winapi::LPDWORD_      lpNumberOfBytes,
65         ::boost::winapi::ULONG_PTR_    *lpCompletionKey,
66         ::boost::winapi::LPOVERLAPPED_ *lpOverlapped,
67         ::boost::winapi::DWORD_        dwMilliseconds)
68 {
69     return ::GetQueuedCompletionStatus(
70                 CompletionPort,
71                 lpNumberOfBytes,
72                 lpCompletionKey,
73                 reinterpret_cast<::_OVERLAPPED**>(lpOverlapped),
74                 dwMilliseconds);
75 }
76 
77 #if defined( BOOST_USE_WINDOWS_H )
78 
79 constexpr auto static JobObjectExtendedLimitInformation_ = ::JobObjectExtendedLimitInformation;
80 constexpr auto static JobObjectAssociateCompletionPortInformation_ = ::JobObjectAssociateCompletionPortInformation;
81 constexpr auto static JobObjectBasicAccountingInformation_ = ::JobObjectBasicAccountingInformation;
82 
83 using JOBOBJECT_BASIC_LIMIT_INFORMATION_ = ::JOBOBJECT_BASIC_LIMIT_INFORMATION;
84 using JOBOBJECTINFOCLASS_ = ::JOBOBJECTINFOCLASS;
85 using IO_COUNTERS_ = ::IO_COUNTERS;
86 using JOBOBJECT_EXTENDED_LIMIT_INFORMATION_ = ::JOBOBJECT_EXTENDED_LIMIT_INFORMATION;
87 using JOBOBJECT_BASIC_ACCOUNTING_INFORMATION_ = ::JOBOBJECT_BASIC_ACCOUNTING_INFORMATION;
88 
query_information_job_object(::boost::winapi::HANDLE_ hJob,JOBOBJECTINFOCLASS_ JobObjectInfoClass,void * lpJobObjectInfo,::boost::winapi::DWORD_ cbJobObjectInfoLength,::boost::winapi::DWORD_ * lpReturnLength)89 inline ::boost::winapi::BOOL_ query_information_job_object(
90         ::boost::winapi::HANDLE_ hJob,
91         JOBOBJECTINFOCLASS_ JobObjectInfoClass,
92         void * lpJobObjectInfo,
93         ::boost::winapi::DWORD_ cbJobObjectInfoLength,
94         ::boost::winapi::DWORD_ *lpReturnLength)
95 {
96     return ::QueryInformationJobObject(hJob, JobObjectInfoClass, lpJobObjectInfo, cbJobObjectInfoLength, lpReturnLength);
97 }
98 
set_information_job_object(::boost::winapi::HANDLE_ hJob,JOBOBJECTINFOCLASS_ JobObjectInfoClass,void * lpJobObjectInfo,::boost::winapi::DWORD_ cbJobObjectInfoLength)99 inline ::boost::winapi::BOOL_ set_information_job_object(
100         ::boost::winapi::HANDLE_ hJob,
101         JOBOBJECTINFOCLASS_ JobObjectInfoClass,
102         void * lpJobObjectInfo,
103         ::boost::winapi::DWORD_ cbJobObjectInfoLength)
104 {
105     return ::SetInformationJobObject(hJob, JobObjectInfoClass, lpJobObjectInfo, cbJobObjectInfoLength);
106 }
107 
108 
109 #else
110 
111 //this import workaround is to keep it a header-only library. and enums cannot be imported from the winapi.
112 
113 extern "C"
114 {
115 
116 typedef enum _JOBOBJECTINFOCLASS_
117 {
118     JobObjectBasicAccountingInformation_ = 1,
119     JobObjectBasicLimitInformation_,
120     JobObjectBasicProcessIdList_,
121     JobObjectBasicUIRestrictions_,
122     JobObjectSecurityLimitInformation_,
123     JobObjectEndOfJobTimeInformation_,
124     JobObjectAssociateCompletionPortInformation_,
125     JobObjectBasicAndIoAccountingInformation_,
126     JobObjectExtendedLimitInformation_,
127     JobObjectJobSetInformation_,
128     JobObjectGroupInformation_,
129     JobObjectNotificationLimitInformation_,
130     JobObjectLimitViolationInformation_,
131     JobObjectGroupInformationEx_,
132     JobObjectCpuRateControlInformation_,
133     JobObjectCompletionFilter_,
134     JobObjectCompletionCounter_,
135     JobObjectReserved1Information_ = 18,
136     JobObjectReserved2Information_,
137     JobObjectReserved3Information_,
138     JobObjectReserved4Information_,
139     JobObjectReserved5Information_,
140     JobObjectReserved6Information_,
141     JobObjectReserved7Information_,
142     JobObjectReserved8Information_,
143     MaxJobObjectInfoClass_
144 } JOBOBJECTINFOCLASS_;
145 
146 typedef struct _JOBOBJECT_BASIC_LIMIT_INFORMATION_
147 {
148     ::boost::winapi::LARGE_INTEGER_ PerProcessUserTimeLimit;
149     ::boost::winapi::LARGE_INTEGER_ PerJobUserTimeLimit;
150     ::boost::winapi::DWORD_ LimitFlags;
151     ::boost::winapi::SIZE_T_ MinimumWorkingSetSize;
152     ::boost::winapi::SIZE_T_ MaximumWorkingSetSize;
153     ::boost::winapi::DWORD_ ActiveProcessLimit;
154     ::boost::winapi::ULONG_PTR_ Affinity;
155     ::boost::winapi::DWORD_ PriorityClass;
156     ::boost::winapi::DWORD_ SchedulingClass;
157 } JOBOBJECT_BASIC_LIMIT_INFORMATION_;
158 
159 
160 typedef struct _JOBOBJECT_BASIC_ACCOUNTING_INFORMATION_ {
161     ::boost::winapi::LARGE_INTEGER_ TotalUserTime;
162     ::boost::winapi::LARGE_INTEGER_ TotalKernelTime;
163     ::boost::winapi::LARGE_INTEGER_ ThisPeriodTotalUserTime;
164     ::boost::winapi::LARGE_INTEGER_ ThisPeriodTotalKernelTime;
165     ::boost::winapi::DWORD_         TotalPageFaultCount;
166     ::boost::winapi::DWORD_         TotalProcesses;
167     ::boost::winapi::DWORD_         ActiveProcesses;
168     ::boost::winapi::DWORD_         TotalTerminatedProcesses;
169 } JOBOBJECT_BASIC_ACCOUNTING_INFORMATION_;
170 
171 typedef struct _IO_COUNTERS_
172 {
173     ::boost::winapi::ULONGLONG_ ReadOperationCount;
174     ::boost::winapi::ULONGLONG_ WriteOperationCount;
175     ::boost::winapi::ULONGLONG_ OtherOperationCount;
176     ::boost::winapi::ULONGLONG_ ReadTransferCount;
177     ::boost::winapi::ULONGLONG_ WriteTransferCount;
178     ::boost::winapi::ULONGLONG_ OtherTransferCount;
179 } IO_COUNTERS_;
180 
181 
182 typedef struct _JOBOBJECT_EXTENDED_LIMIT_INFORMATION_
183 {
184     JOBOBJECT_BASIC_LIMIT_INFORMATION_ BasicLimitInformation;
185     IO_COUNTERS_ IoInfo;
186     ::boost::winapi::SIZE_T_ ProcessMemoryLimit;
187     ::boost::winapi::SIZE_T_ JobMemoryLimit;
188     ::boost::winapi::SIZE_T_ PeakProcessMemoryUsed;
189     ::boost::winapi::SIZE_T_ PeakJobMemoryUsed;
190 } JOBOBJECT_EXTENDED_LIMIT_INFORMATION_;
191 
192 
193 /*BOOL WINAPI QueryInformationJobObject(
194   _In_opt_  HANDLE             hJob,
195   _In_      JOBOBJECTINFOCLASS JobObjectInfoClass,
196   _Out_     LPVOID             lpJobObjectInfo,
197   _In_      DWORD              cbJobObjectInfoLength,
198   _Out_opt_ LPDWORD            lpReturnLength
199 );
200  */
201 typedef ::boost::winapi::BOOL_ (BOOST_WINAPI_WINAPI_CC *query_information_job_object_p)(
202         ::boost::winapi::HANDLE_,
203         JOBOBJECTINFOCLASS_,
204         void *,
205         ::boost::winapi::DWORD_,
206         ::boost::winapi::DWORD_ *);
207 
208 
query_information_job_object(::boost::winapi::HANDLE_ hJob,JOBOBJECTINFOCLASS_ JobObjectInfoClass,void * lpJobObjectInfo,::boost::winapi::DWORD_ cbJobObjectInfoLength,::boost::winapi::DWORD_ * lpReturnLength)209 inline ::boost::winapi::BOOL_ query_information_job_object(
210         ::boost::winapi::HANDLE_ hJob,
211         JOBOBJECTINFOCLASS_ JobObjectInfoClass,
212         void *lpJobObjectInfo,
213         ::boost::winapi::DWORD_ cbJobObjectInfoLength,
214         ::boost::winapi::DWORD_ *lpReturnLength)
215 {
216     static ::boost::winapi::HMODULE_ h = ::boost::winapi::get_module_handle(
217             L"Kernel32.dll");
218     static query_information_job_object_p f = reinterpret_cast<query_information_job_object_p>(::boost::winapi::get_proc_address(
219             h, "QueryInformationJobObject"));
220 
221     return (*f)(hJob, JobObjectInfoClass, lpJobObjectInfo,
222                 cbJobObjectInfoLength, lpReturnLength);
223 }
224 
225 /*BOOL WINAPI SetInformationJobObject(
226   _In_ HANDLE             hJob,
227   _In_ JOBOBJECTINFOCLASS JobObjectInfoClass,
228   _In_ LPVOID             lpJobObjectInfo,
229   _In_ DWORD              cbJobObjectInfoLength
230 );*/
231 
232 typedef ::boost::winapi::BOOL_ (BOOST_WINAPI_WINAPI_CC *set_information_job_object_p)(
233         ::boost::winapi::HANDLE_,
234         JOBOBJECTINFOCLASS_,
235         void *,
236         ::boost::winapi::DWORD_);
237 
238 }
239 
set_information_job_object(::boost::winapi::HANDLE_ hJob,JOBOBJECTINFOCLASS_ JobObjectInfoClass,void * lpJobObjectInfo,::boost::winapi::DWORD_ cbJobObjectInfoLength)240 inline ::boost::winapi::BOOL_ set_information_job_object(
241         ::boost::winapi::HANDLE_ hJob,
242         JOBOBJECTINFOCLASS_ JobObjectInfoClass,
243         void *lpJobObjectInfo,
244         ::boost::winapi::DWORD_ cbJobObjectInfoLength)
245 {
246     static ::boost::winapi::HMODULE_ h = ::boost::winapi::get_module_handle(
247             L"Kernel32.dll");
248     static set_information_job_object_p f = reinterpret_cast<set_information_job_object_p>(::boost::winapi::get_proc_address(
249             h, "SetInformationJobObject"));
250 
251     return (*f)(hJob, JobObjectInfoClass, lpJobObjectInfo,
252                 cbJobObjectInfoLength);
253 }
254 
255 #endif
256 
257 constexpr static ::boost::winapi::DWORD_ JOB_OBJECT_LIMIT_BREAKAWAY_OK_ = 0x00000800;
258 
259 }}}}}
260 
261 #endif /* BOOST_PROCESS_DETAIL_WINDOWS_JOB_WORKAROUND_HPP_ */
262