You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
105 lines
3.1 KiB
Python
105 lines
3.1 KiB
Python
2 years ago
|
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
# Licensed under the MIT License. See LICENSE in the project root
|
||
|
# for license information.
|
||
|
|
||
|
import ctypes
|
||
|
from ctypes.wintypes import BOOL, DWORD, HANDLE, LARGE_INTEGER, LPCSTR, UINT
|
||
|
|
||
|
from debugpy.common import log
|
||
|
|
||
|
|
||
|
JOBOBJECTCLASS = ctypes.c_int
|
||
|
LPDWORD = ctypes.POINTER(DWORD)
|
||
|
LPVOID = ctypes.c_void_p
|
||
|
SIZE_T = ctypes.c_size_t
|
||
|
ULONGLONG = ctypes.c_ulonglong
|
||
|
|
||
|
|
||
|
class IO_COUNTERS(ctypes.Structure):
|
||
|
_fields_ = [
|
||
|
("ReadOperationCount", ULONGLONG),
|
||
|
("WriteOperationCount", ULONGLONG),
|
||
|
("OtherOperationCount", ULONGLONG),
|
||
|
("ReadTransferCount", ULONGLONG),
|
||
|
("WriteTransferCount", ULONGLONG),
|
||
|
("OtherTransferCount", ULONGLONG),
|
||
|
]
|
||
|
|
||
|
|
||
|
class JOBOBJECT_BASIC_LIMIT_INFORMATION(ctypes.Structure):
|
||
|
_fields_ = [
|
||
|
("PerProcessUserTimeLimit", LARGE_INTEGER),
|
||
|
("PerJobUserTimeLimit", LARGE_INTEGER),
|
||
|
("LimitFlags", DWORD),
|
||
|
("MinimumWorkingSetSize", SIZE_T),
|
||
|
("MaximumWorkingSetSize", SIZE_T),
|
||
|
("ActiveProcessLimit", DWORD),
|
||
|
("Affinity", SIZE_T),
|
||
|
("PriorityClass", DWORD),
|
||
|
("SchedulingClass", DWORD),
|
||
|
]
|
||
|
|
||
|
|
||
|
class JOBOBJECT_EXTENDED_LIMIT_INFORMATION(ctypes.Structure):
|
||
|
_fields_ = [
|
||
|
("BasicLimitInformation", JOBOBJECT_BASIC_LIMIT_INFORMATION),
|
||
|
("IoInfo", IO_COUNTERS),
|
||
|
("ProcessMemoryLimit", SIZE_T),
|
||
|
("JobMemoryLimit", SIZE_T),
|
||
|
("PeakProcessMemoryUsed", SIZE_T),
|
||
|
("PeakJobMemoryUsed", SIZE_T),
|
||
|
]
|
||
|
|
||
|
|
||
|
JobObjectExtendedLimitInformation = JOBOBJECTCLASS(9)
|
||
|
|
||
|
JOB_OBJECT_LIMIT_BREAKAWAY_OK = 0x00000800
|
||
|
JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE = 0x00002000
|
||
|
|
||
|
PROCESS_TERMINATE = 0x0001
|
||
|
PROCESS_SET_QUOTA = 0x0100
|
||
|
|
||
|
|
||
|
def _errcheck(is_error_result=(lambda result: not result)):
|
||
|
def impl(result, func, args):
|
||
|
if is_error_result(result):
|
||
|
log.debug("{0} returned {1}", func.__name__, result)
|
||
|
raise ctypes.WinError()
|
||
|
else:
|
||
|
return result
|
||
|
|
||
|
return impl
|
||
|
|
||
|
|
||
|
kernel32 = ctypes.windll.kernel32
|
||
|
|
||
|
kernel32.AssignProcessToJobObject.errcheck = _errcheck()
|
||
|
kernel32.AssignProcessToJobObject.restype = BOOL
|
||
|
kernel32.AssignProcessToJobObject.argtypes = (HANDLE, HANDLE)
|
||
|
|
||
|
kernel32.CreateJobObjectA.errcheck = _errcheck(lambda result: result == 0)
|
||
|
kernel32.CreateJobObjectA.restype = HANDLE
|
||
|
kernel32.CreateJobObjectA.argtypes = (LPVOID, LPCSTR)
|
||
|
|
||
|
kernel32.OpenProcess.errcheck = _errcheck(lambda result: result == 0)
|
||
|
kernel32.OpenProcess.restype = HANDLE
|
||
|
kernel32.OpenProcess.argtypes = (DWORD, BOOL, DWORD)
|
||
|
|
||
|
kernel32.QueryInformationJobObject.errcheck = _errcheck()
|
||
|
kernel32.QueryInformationJobObject.restype = BOOL
|
||
|
kernel32.QueryInformationJobObject.argtypes = (
|
||
|
HANDLE,
|
||
|
JOBOBJECTCLASS,
|
||
|
LPVOID,
|
||
|
DWORD,
|
||
|
LPDWORD,
|
||
|
)
|
||
|
|
||
|
kernel32.SetInformationJobObject.errcheck = _errcheck()
|
||
|
kernel32.SetInformationJobObject.restype = BOOL
|
||
|
kernel32.SetInformationJobObject.argtypes = (HANDLE, JOBOBJECTCLASS, LPVOID, DWORD)
|
||
|
|
||
|
kernel32.TerminateJobObject.errcheck = _errcheck()
|
||
|
kernel32.TerminateJobObject.restype = BOOL
|
||
|
kernel32.TerminateJobObject.argtypes = (HANDLE, UINT)
|