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