##// END OF EJS Templates
killdaemons: drop superfluous L suffix from constant...
Augie Fackler -
r20698:1147563f default
parent child Browse files
Show More
@@ -1,92 +1,91 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 PROCESS_QUERY_INFORMATION = 0x400
18 PROCESS_QUERY_INFORMATION = 0x400
19 SYNCHRONIZE = 0x00100000L
19 SYNCHRONIZE = 0x00100000
20 WAIT_OBJECT_0 = 0
20 WAIT_OBJECT_0 = 0
21 WAIT_TIMEOUT = 258
21 WAIT_TIMEOUT = 258
22 handle = ctypes.windll.kernel32.OpenProcess(
22 handle = ctypes.windll.kernel32.OpenProcess(
23 PROCESS_TERMINATE|SYNCHRONIZE|PROCESS_QUERY_INFORMATION,
23 PROCESS_TERMINATE|SYNCHRONIZE|PROCESS_QUERY_INFORMATION,
24 False, pid)
24 False, pid)
25 if handle == 0:
25 if handle == 0:
26 _check(0, 87) # err 87 when process not found
26 _check(0, 87) # err 87 when process not found
27 return # process not found, already finished
27 return # process not found, already finished
28 try:
28 try:
29 r = ctypes.windll.kernel32.WaitForSingleObject(handle, 100)
29 r = ctypes.windll.kernel32.WaitForSingleObject(handle, 100)
30 if r == WAIT_OBJECT_0:
30 if r == WAIT_OBJECT_0:
31 pass # terminated, but process handle still available
31 pass # terminated, but process handle still available
32 elif r == WAIT_TIMEOUT:
32 elif r == WAIT_TIMEOUT:
33 _check(ctypes.windll.kernel32.TerminateProcess(handle, -1))
33 _check(ctypes.windll.kernel32.TerminateProcess(handle, -1))
34 else:
34 else:
35 _check(r)
35 _check(r)
36
36
37 # TODO?: forcefully kill when timeout
37 # TODO?: forcefully kill when timeout
38 # and ?shorter waiting time? when tryhard==True
38 # and ?shorter waiting time? when tryhard==True
39 r = ctypes.windll.kernel32.WaitForSingleObject(handle, 100)
39 r = ctypes.windll.kernel32.WaitForSingleObject(handle, 100)
40 # timeout = 100 ms
40 # timeout = 100 ms
41 if r == WAIT_OBJECT_0:
41 if r == WAIT_OBJECT_0:
42 pass # process is terminated
42 pass # process is terminated
43 elif r == WAIT_TIMEOUT:
43 elif r == WAIT_TIMEOUT:
44 logfn('# Daemon process %d is stuck')
44 logfn('# Daemon process %d is stuck')
45 else:
45 else:
46 check(r) # any error
46 check(r) # any error
47 except: #re-raises
47 except: #re-raises
48 ctypes.windll.kernel32.CloseHandle(handle) # no _check, keep error
48 ctypes.windll.kernel32.CloseHandle(handle) # no _check, keep error
49 raise
49 raise
50 _check(ctypes.windll.kernel32.CloseHandle(handle))
50 _check(ctypes.windll.kernel32.CloseHandle(handle))
51
51
52 else:
52 else:
53 def kill(pid, logfn, tryhard=True):
53 def kill(pid, logfn, tryhard=True):
54 try:
54 try:
55 os.kill(pid, 0)
55 os.kill(pid, 0)
56 logfn('# Killing daemon process %d' % pid)
56 logfn('# Killing daemon process %d' % pid)
57 os.kill(pid, signal.SIGTERM)
57 os.kill(pid, signal.SIGTERM)
58 if tryhard:
58 if tryhard:
59 for i in range(10):
59 for i in range(10):
60 time.sleep(0.05)
60 time.sleep(0.05)
61 os.kill(pid, 0)
61 os.kill(pid, 0)
62 else:
62 else:
63 time.sleep(0.1)
63 time.sleep(0.1)
64 os.kill(pid, 0)
64 os.kill(pid, 0)
65 logfn('# Daemon process %d is stuck - really killing it' % pid)
65 logfn('# Daemon process %d is stuck - really killing it' % pid)
66 os.kill(pid, signal.SIGKILL)
66 os.kill(pid, signal.SIGKILL)
67 except OSError, err:
67 except OSError, err:
68 if err.errno != errno.ESRCH:
68 if err.errno != errno.ESRCH:
69 raise
69 raise
70
70
71 def killdaemons(pidfile, tryhard=True, remove=False, logfn=None):
71 def killdaemons(pidfile, tryhard=True, remove=False, logfn=None):
72 if not logfn:
72 if not logfn:
73 logfn = lambda s: s
73 logfn = lambda s: s
74 # Kill off any leftover daemon processes
74 # Kill off any leftover daemon processes
75 try:
75 try:
76 fp = open(pidfile)
76 fp = open(pidfile)
77 for line in fp:
77 for line in fp:
78 try:
78 try:
79 pid = int(line)
79 pid = int(line)
80 except ValueError:
80 except ValueError:
81 continue
81 continue
82 kill(pid, logfn, tryhard)
82 kill(pid, logfn, tryhard)
83 fp.close()
83 fp.close()
84 if remove:
84 if remove:
85 os.unlink(pidfile)
85 os.unlink(pidfile)
86 except IOError:
86 except IOError:
87 pass
87 pass
88
88
89 if __name__ == '__main__':
89 if __name__ == '__main__':
90 path, = sys.argv[1:]
90 path, = sys.argv[1:]
91 killdaemons(path)
91 killdaemons(path)
92
General Comments 0
You need to be logged in to leave comments. Login now