pymake/win32process.py
author Benjamin Smedberg <benjamin@smedbergs.us>
Thu, 26 Feb 2009 20:32:19 -0500
branchresolve-perf
changeset 191 7a8dc41115d67e05b6da433da2f7685ca9941b02
parent 164 5efdf02bf3d91cfb72195dd02159ea7e16605e46
permissions -rw-r--r--
I noticed Expansion.resolve still comes up really high on perf charts. This patch makes it much easier to resolve expansions which are just literals, which is very common for variable names. Unfortunately, this makes the code a fair bit more complex, and doesn't help nearly as much as I'd like. I'm beginning to wonder if getting gmake performance parity is impossible, or at least improbable given the current architecture: but I can't think of an alternate architecture that is better.

from ctypes import windll, POINTER, byref, WinError
from ctypes.wintypes import WINFUNCTYPE, HANDLE, DWORD, BOOL

INFINITE = -1
WAIT_FAILED = 0xFFFFFFFF

LPDWORD = POINTER(DWORD)
_GetExitCodeProcessProto = WINFUNCTYPE(BOOL, HANDLE, LPDWORD)
_GetExitCodeProcess = _GetExitCodeProcessProto(("GetExitCodeProcess", windll.kernel32))
def GetExitCodeProcess(h):
    exitcode = DWORD()
    r = _GetExitCodeProcess(h, byref(exitcode))
    if r is 0:
        raise WinError()
    return exitcode.value

_WaitForMultipleObjectsProto = WINFUNCTYPE(DWORD, DWORD, POINTER(HANDLE), BOOL, DWORD)
_WaitForMultipleObjects = _WaitForMultipleObjectsProto(("WaitForMultipleObjects", windll.kernel32))

def WaitForAnyProcess(processes):
    arrtype = HANDLE * len(processes)
    harray = arrtype(*(int(p._handle) for p in processes))

    r = _WaitForMultipleObjects(len(processes), harray, False, INFINITE)
    if r == WAIT_FAILED:
        raise WinError()

    return processes[r], GetExitCodeProcess(int(processes[r]._handle)) <<8