--- 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: