# HG changeset patch # User Christian Ebert # Date 1392367933 -3600 # Node ID 90d2e5021063b448d2f77faf00a9baa885c0a920 # Parent 7fb45860e26779024c0679d9a09ce7cf332f85ff# Parent e307d04d3c4df8a1cc8221c3ec7d9c2410bf5a94 Merge with stable diff -r 7fb45860e267 -r 90d2e5021063 tests/killdaemons.py --- a/tests/killdaemons.py Tue Feb 11 22:50:56 2014 +0100 +++ b/tests/killdaemons.py Fri Feb 14 09:52:13 2014 +0100 @@ -4,13 +4,51 @@ if os.name =='nt': import ctypes + + def _check(ret, expectederr=None): + if ret == 0: + winerrno = ctypes.GetLastError() + if winerrno == expectederr: + return True + raise ctypes.WinError(winerrno) + def kill(pid, logfn, tryhard=True): logfn('# Killing daemon process %d' % pid) PROCESS_TERMINATE = 1 + PROCESS_QUERY_INFORMATION = 0x400 + SYNCHRONIZE = 0x00100000L + WAIT_OBJECT_0 = 0 + WAIT_TIMEOUT = 258 handle = ctypes.windll.kernel32.OpenProcess( - PROCESS_TERMINATE, False, pid) - ctypes.windll.kernel32.TerminateProcess(handle, -1) - ctypes.windll.kernel32.CloseHandle(handle) + PROCESS_TERMINATE|SYNCHRONIZE|PROCESS_QUERY_INFORMATION, + False, pid) + if handle == 0: + _check(0, 87) # err 87 when process not found + return # process not found, already finished + try: + r = ctypes.windll.kernel32.WaitForSingleObject(handle, 100) + if r == WAIT_OBJECT_0: + pass # terminated, but process handle still available + elif r == WAIT_TIMEOUT: + _check(ctypes.windll.kernel32.TerminateProcess(handle, -1)) + else: + _check(r) + + # TODO?: forcefully kill when timeout + # and ?shorter waiting time? when tryhard==True + r = ctypes.windll.kernel32.WaitForSingleObject(handle, 100) + # timeout = 100 ms + if r == WAIT_OBJECT_0: + pass # process is terminated + elif r == WAIT_TIMEOUT: + logfn('# Daemon process %d is stuck') + else: + check(r) # any error + except: #re-raises + ctypes.windll.kernel32.CloseHandle(handle) # no _check, keep error + raise + _check(ctypes.windll.kernel32.CloseHandle(handle)) + else: def kill(pid, logfn, tryhard=True): try: