job_workaround.hpp 9.5 KB

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