comparison tests/killdaemons.py @ 43076:2372284d9457

formatting: blacken the codebase This is using my patch to black (https://github.com/psf/black/pull/826) so we don't un-wrap collection literals. Done with: hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**"' | xargs black -S # skip-blame mass-reformatting only # no-check-commit reformats foo_bar functions Differential Revision: https://phab.mercurial-scm.org/D6971
author Augie Fackler <augie@google.com>
date Sun, 06 Oct 2019 09:45:02 -0400
parents 89793289c891
children c102b704edb5
comparison
equal deleted inserted replaced
43075:57875cf423c9 43076:2372284d9457
5 import os 5 import os
6 import signal 6 import signal
7 import sys 7 import sys
8 import time 8 import time
9 9
10 if os.name =='nt': 10 if os.name == 'nt':
11 import ctypes 11 import ctypes
12 12
13 _BOOL = ctypes.c_long 13 _BOOL = ctypes.c_long
14 _DWORD = ctypes.c_ulong 14 _DWORD = ctypes.c_ulong
15 _UINT = ctypes.c_uint 15 _UINT = ctypes.c_uint
44 SYNCHRONIZE = 0x00100000 44 SYNCHRONIZE = 0x00100000
45 WAIT_OBJECT_0 = 0 45 WAIT_OBJECT_0 = 0
46 WAIT_TIMEOUT = 258 46 WAIT_TIMEOUT = 258
47 WAIT_FAILED = _DWORD(0xFFFFFFFF).value 47 WAIT_FAILED = _DWORD(0xFFFFFFFF).value
48 handle = ctypes.windll.kernel32.OpenProcess( 48 handle = ctypes.windll.kernel32.OpenProcess(
49 PROCESS_TERMINATE|SYNCHRONIZE|PROCESS_QUERY_INFORMATION, 49 PROCESS_TERMINATE | SYNCHRONIZE | PROCESS_QUERY_INFORMATION,
50 False, pid) 50 False,
51 pid,
52 )
51 if handle is None: 53 if handle is None:
52 _check(0, 87) # err 87 when process not found 54 _check(0, 87) # err 87 when process not found
53 return # process not found, already finished 55 return # process not found, already finished
54 try: 56 try:
55 r = ctypes.windll.kernel32.WaitForSingleObject(handle, 100) 57 r = ctypes.windll.kernel32.WaitForSingleObject(handle, 100)
56 if r == WAIT_OBJECT_0: 58 if r == WAIT_OBJECT_0:
57 pass # terminated, but process handle still available 59 pass # terminated, but process handle still available
58 elif r == WAIT_TIMEOUT: 60 elif r == WAIT_TIMEOUT:
59 _check(ctypes.windll.kernel32.TerminateProcess(handle, -1)) 61 _check(ctypes.windll.kernel32.TerminateProcess(handle, -1))
60 elif r == WAIT_FAILED: 62 elif r == WAIT_FAILED:
61 _check(0) # err stored in GetLastError() 63 _check(0) # err stored in GetLastError()
62 64
63 # TODO?: forcefully kill when timeout 65 # TODO?: forcefully kill when timeout
64 # and ?shorter waiting time? when tryhard==True 66 # and ?shorter waiting time? when tryhard==True
65 r = ctypes.windll.kernel32.WaitForSingleObject(handle, 100) 67 r = ctypes.windll.kernel32.WaitForSingleObject(handle, 100)
66 # timeout = 100 ms 68 # timeout = 100 ms
67 if r == WAIT_OBJECT_0: 69 if r == WAIT_OBJECT_0:
68 pass # process is terminated 70 pass # process is terminated
69 elif r == WAIT_TIMEOUT: 71 elif r == WAIT_TIMEOUT:
70 logfn('# Daemon process %d is stuck') 72 logfn('# Daemon process %d is stuck')
71 elif r == WAIT_FAILED: 73 elif r == WAIT_FAILED:
72 _check(0) # err stored in GetLastError() 74 _check(0) # err stored in GetLastError()
73 except: #re-raises 75 except: # re-raises
74 ctypes.windll.kernel32.CloseHandle(handle) # no _check, keep error 76 ctypes.windll.kernel32.CloseHandle(handle) # no _check, keep error
75 raise 77 raise
76 _check(ctypes.windll.kernel32.CloseHandle(handle)) 78 _check(ctypes.windll.kernel32.CloseHandle(handle))
77 79
80
78 else: 81 else:
82
79 def kill(pid, logfn, tryhard=True): 83 def kill(pid, logfn, tryhard=True):
80 try: 84 try:
81 os.kill(pid, 0) 85 os.kill(pid, 0)
82 logfn('# Killing daemon process %d' % pid) 86 logfn('# Killing daemon process %d' % pid)
83 os.kill(pid, signal.SIGTERM) 87 os.kill(pid, signal.SIGTERM)
92 os.kill(pid, signal.SIGKILL) 96 os.kill(pid, signal.SIGKILL)
93 except OSError as err: 97 except OSError as err:
94 if err.errno != errno.ESRCH: 98 if err.errno != errno.ESRCH:
95 raise 99 raise
96 100
101
97 def killdaemons(pidfile, tryhard=True, remove=False, logfn=None): 102 def killdaemons(pidfile, tryhard=True, remove=False, logfn=None):
98 if not logfn: 103 if not logfn:
99 logfn = lambda s: s 104 logfn = lambda s: s
100 # Kill off any leftover daemon processes 105 # Kill off any leftover daemon processes
101 try: 106 try:
105 try: 110 try:
106 pid = int(line) 111 pid = int(line)
107 if pid <= 0: 112 if pid <= 0:
108 raise ValueError 113 raise ValueError
109 except ValueError: 114 except ValueError:
110 logfn('# Not killing daemon process %s - invalid pid' 115 logfn(
111 % line.rstrip()) 116 '# Not killing daemon process %s - invalid pid'
117 % line.rstrip()
118 )
112 continue 119 continue
113 pids.append(pid) 120 pids.append(pid)
114 for pid in pids: 121 for pid in pids:
115 kill(pid, logfn, tryhard) 122 kill(pid, logfn, tryhard)
116 if remove: 123 if remove:
117 os.unlink(pidfile) 124 os.unlink(pidfile)
118 except IOError: 125 except IOError:
119 pass 126 pass
120 127
128
121 if __name__ == '__main__': 129 if __name__ == '__main__':
122 if len(sys.argv) > 1: 130 if len(sys.argv) > 1:
123 path, = sys.argv[1:] 131 (path,) = sys.argv[1:]
124 else: 132 else:
125 path = os.environ["DAEMON_PIDS"] 133 path = os.environ["DAEMON_PIDS"]
126 134
127 killdaemons(path, remove=True) 135 killdaemons(path, remove=True)