Index: src/third_party/pylib/mozrunner/qijo.py |
=================================================================== |
--- src/third_party/pylib/mozrunner/qijo.py (revision 9275) |
+++ src/third_party/pylib/mozrunner/qijo.py (working copy) |
@@ -1,162 +0,0 @@ |
-from ctypes import c_void_p, POINTER, sizeof, Structure, windll, WinError, WINFUNCTYPE, addressof, c_size_t, c_ulong |
-from ctypes.wintypes import BOOL, BYTE, DWORD, HANDLE, LARGE_INTEGER |
- |
-LPVOID = c_void_p |
-LPDWORD = POINTER(DWORD) |
-SIZE_T = c_size_t |
-ULONG_PTR = POINTER(c_ulong) |
- |
-# A ULONGLONG is a 64-bit unsigned integer. |
-# Thus there are 8 bytes in a ULONGLONG. |
-# XXX why not import c_ulonglong ? |
-ULONGLONG = BYTE * 8 |
- |
-class IO_COUNTERS(Structure): |
- # The IO_COUNTERS struct is 6 ULONGLONGs. |
- # TODO: Replace with non-dummy fields. |
- _fields_ = [('dummy', ULONGLONG * 6)] |
- |
-class JOBOBJECT_BASIC_ACCOUNTING_INFORMATION(Structure): |
- _fields_ = [('TotalUserTime', LARGE_INTEGER), |
- ('TotalKernelTime', LARGE_INTEGER), |
- ('ThisPeriodTotalUserTime', LARGE_INTEGER), |
- ('ThisPeriodTotalKernelTime', LARGE_INTEGER), |
- ('TotalPageFaultCount', DWORD), |
- ('TotalProcesses', DWORD), |
- ('ActiveProcesses', DWORD), |
- ('TotalTerminatedProcesses', DWORD)] |
- |
-class JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION(Structure): |
- _fields_ = [('BasicInfo', JOBOBJECT_BASIC_ACCOUNTING_INFORMATION), |
- ('IoInfo', IO_COUNTERS)] |
- |
-# see http://msdn.microsoft.com/en-us/library/ms684147%28VS.85%29.aspx |
-class JOBOBJECT_BASIC_LIMIT_INFORMATION(Structure): |
- _fields_ = [('PerProcessUserTimeLimit', LARGE_INTEGER), |
- ('PerJobUserTimeLimit', LARGE_INTEGER), |
- ('LimitFlags', DWORD), |
- ('MinimumWorkingSetSize', SIZE_T), |
- ('MaximumWorkingSetSize', SIZE_T), |
- ('ActiveProcessLimit', DWORD), |
- ('Affinity', ULONG_PTR), |
- ('PriorityClass', DWORD), |
- ('SchedulingClass', DWORD) |
- ] |
- |
-# see http://msdn.microsoft.com/en-us/library/ms684156%28VS.85%29.aspx |
-class JOBOBJECT_EXTENDED_LIMIT_INFORMATION(Structure): |
- _fields_ = [('BasicLimitInformation', JOBOBJECT_BASIC_LIMIT_INFORMATION), |
- ('IoInfo', IO_COUNTERS), |
- ('ProcessMemoryLimit', SIZE_T), |
- ('JobMemoryLimit', SIZE_T), |
- ('PeakProcessMemoryUsed', SIZE_T), |
- ('PeakJobMemoryUsed', SIZE_T)] |
- |
-# XXX Magical numbers like 8 should be documented |
-JobObjectBasicAndIoAccountingInformation = 8 |
- |
-# ...like magical number 9 comes from |
-# http://community.flexerasoftware.com/archive/index.php?t-181670.html |
-# I wish I had a more canonical source |
-JobObjectExtendedLimitInformation = 9 |
- |
-class JobObjectInfo(object): |
- mapping = { 'JobObjectBasicAndIoAccountingInformation': 8, |
- 'JobObjectExtendedLimitInformation': 9 |
- } |
- structures = { 8: JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION, |
- 9: JOBOBJECT_EXTENDED_LIMIT_INFORMATION |
- } |
- def __init__(self, _class): |
- if isinstance(_class, basestring): |
- assert _class in self.mapping, 'Class should be one of %s; you gave %s' % (self.mapping, _class) |
- _class = self.mapping[_class] |
- assert _class in self.structures, 'Class should be one of %s; you gave %s' % (self.structures, _class) |
- self.code = _class |
- self.info = self.structures[_class]() |
- |
- |
-QueryInformationJobObjectProto = WINFUNCTYPE( |
- BOOL, # Return type |
- HANDLE, # hJob |
- DWORD, # JobObjectInfoClass |
- LPVOID, # lpJobObjectInfo |
- DWORD, # cbJobObjectInfoLength |
- LPDWORD # lpReturnLength |
- ) |
- |
-QueryInformationJobObjectFlags = ( |
- (1, 'hJob'), |
- (1, 'JobObjectInfoClass'), |
- (1, 'lpJobObjectInfo'), |
- (1, 'cbJobObjectInfoLength'), |
- (1, 'lpReturnLength', None) |
- ) |
- |
-_QueryInformationJobObject = QueryInformationJobObjectProto( |
- ('QueryInformationJobObject', windll.kernel32), |
- QueryInformationJobObjectFlags |
- ) |
- |
-class SubscriptableReadOnlyStruct(object): |
- def __init__(self, struct): |
- self._struct = struct |
- |
- def _delegate(self, name): |
- result = getattr(self._struct, name) |
- if isinstance(result, Structure): |
- return SubscriptableReadOnlyStruct(result) |
- return result |
- |
- def __getitem__(self, name): |
- match = [fname for fname, ftype in self._struct._fields_ |
- if fname == name] |
- if match: |
- return self._delegate(name) |
- raise KeyError(name) |
- |
- def __getattr__(self, name): |
- return self._delegate(name) |
- |
-def QueryInformationJobObject(hJob, JobObjectInfoClass): |
- jobinfo = JobObjectInfo(JobObjectInfoClass) |
- result = _QueryInformationJobObject( |
- hJob=hJob, |
- JobObjectInfoClass=jobinfo.code, |
- lpJobObjectInfo=addressof(jobinfo.info), |
- cbJobObjectInfoLength=sizeof(jobinfo.info) |
- ) |
- if not result: |
- raise WinError() |
- return SubscriptableReadOnlyStruct(jobinfo.info) |
- |
-def test_qijo(): |
- from killableprocess import Popen |
- |
- popen = Popen('c:\\windows\\notepad.exe') |
- |
- try: |
- result = QueryInformationJobObject(0, 8) |
- raise AssertionError('throw should occur') |
- except WindowsError, e: |
- pass |
- |
- try: |
- result = QueryInformationJobObject(0, 1) |
- raise AssertionError('throw should occur') |
- except NotImplementedError, e: |
- pass |
- |
- result = QueryInformationJobObject(popen._job, 8) |
- if result['BasicInfo']['ActiveProcesses'] != 1: |
- raise AssertionError('expected ActiveProcesses to be 1') |
- popen.kill() |
- |
- result = QueryInformationJobObject(popen._job, 8) |
- if result.BasicInfo.ActiveProcesses != 0: |
- raise AssertionError('expected ActiveProcesses to be 0') |
- |
-if __name__ == '__main__': |
- print "testing." |
- test_qijo() |
- print "success!" |