##// END OF EJS Templates
tests: killdaemons.py for windows distinguishes access violation and terminated...
Simon Heimberg -
r20496:acbd19b9 default
parent child Browse files
Show More
@@ -1,85 +1,92 b''
1 1 #!/usr/bin/env python
2 2
3 3 import os, sys, time, errno, signal
4 4
5 5 if os.name =='nt':
6 6 import ctypes
7 7
8 8 def _check(ret, expectederr=None):
9 9 if ret == 0:
10 10 winerrno = ctypes.GetLastError()
11 11 if winerrno == expectederr:
12 12 return True
13 13 raise ctypes.WinError(winerrno)
14 14
15 15 def kill(pid, logfn, tryhard=True):
16 16 logfn('# Killing daemon process %d' % pid)
17 17 PROCESS_TERMINATE = 1
18 PROCESS_QUERY_INFORMATION = 0x400
18 19 SYNCHRONIZE = 0x00100000L
19 20 WAIT_OBJECT_0 = 0
20 21 WAIT_TIMEOUT = 258
21 22 handle = ctypes.windll.kernel32.OpenProcess(
22 PROCESS_TERMINATE|SYNCHRONIZE, False, pid)
23 PROCESS_TERMINATE|SYNCHRONIZE|PROCESS_QUERY_INFORMATION,
24 False, pid)
23 25 if handle == 0:
24 26 _check(0, 87) # err 87 when process not found
25 27 return # process not found, already finished
26 28 try:
27 _check(ctypes.windll.kernel32.TerminateProcess(handle, -1), 5)
28 # windows error 5 when process does not exist or no access TODO
29 r = ctypes.windll.kernel32.WaitForSingleObject(handle, 100)
30 if r == WAIT_OBJECT_0:
31 pass # terminated, but process handle still available
32 elif r == WAIT_TIMEOUT:
33 _check(ctypes.windll.kernel32.TerminateProcess(handle, -1))
34 else:
35 _check(r)
29 36
30 37 # TODO?: forcefully kill when timeout
31 38 # and ?shorter waiting time? when tryhard==True
32 39 r = ctypes.windll.kernel32.WaitForSingleObject(handle, 100)
33 40 # timeout = 100 ms
34 41 if r == WAIT_OBJECT_0:
35 42 pass # process is terminated
36 43 elif r == WAIT_TIMEOUT:
37 44 logfn('# Daemon process %d is stuck')
38 45 else:
39 46 check(r) # any error
40 47 except: #re-raises
41 48 ctypes.windll.kernel32.CloseHandle(handle) # no _check, keep error
42 49 raise
43 50 _check(ctypes.windll.kernel32.CloseHandle(handle))
44 51
45 52 else:
46 53 def kill(pid, logfn, tryhard=True):
47 54 try:
48 55 os.kill(pid, 0)
49 56 logfn('# Killing daemon process %d' % pid)
50 57 os.kill(pid, signal.SIGTERM)
51 58 if tryhard:
52 59 for i in range(10):
53 60 time.sleep(0.05)
54 61 os.kill(pid, 0)
55 62 else:
56 63 time.sleep(0.1)
57 64 os.kill(pid, 0)
58 65 logfn('# Daemon process %d is stuck - really killing it' % pid)
59 66 os.kill(pid, signal.SIGKILL)
60 67 except OSError, err:
61 68 if err.errno != errno.ESRCH:
62 69 raise
63 70
64 71 def killdaemons(pidfile, tryhard=True, remove=False, logfn=None):
65 72 if not logfn:
66 73 logfn = lambda s: s
67 74 # Kill off any leftover daemon processes
68 75 try:
69 76 fp = open(pidfile)
70 77 for line in fp:
71 78 try:
72 79 pid = int(line)
73 80 except ValueError:
74 81 continue
75 82 kill(pid, logfn, tryhard)
76 83 fp.close()
77 84 if remove:
78 85 os.unlink(pidfile)
79 86 except IOError:
80 87 pass
81 88
82 89 if __name__ == '__main__':
83 90 path, = sys.argv[1:]
84 91 killdaemons(path)
85 92
General Comments 0
You need to be logged in to leave comments. Login now