job_workaround.hpp 9.6 KB

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