Spaces:
Paused
Paused
| # 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) | |