| 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!"
|
|
|