Mercurial > evolve
annotate tests/killdaemons.py @ 1452:1bcbd14cf159 stable
merge back with 3.3 compat branch
author | Pierre-Yves David <pierre-yves.david@fb.com> |
---|---|
date | Thu, 25 Jun 2015 17:37:43 -0700 |
parents | 88e61e45026d |
children |
rev | line source |
---|---|
7
cc592295900f
Add write protocol support for private.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff
changeset
|
1 #!/usr/bin/env python |
cc592295900f
Add write protocol support for private.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff
changeset
|
2 |
1222
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
3 import os, sys, time, errno, signal |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
4 |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
5 if os.name =='nt': |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
6 import ctypes |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
7 |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
8 def _check(ret, expectederr=None): |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
9 if ret == 0: |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
10 winerrno = ctypes.GetLastError() |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
11 if winerrno == expectederr: |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
12 return True |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
13 raise ctypes.WinError(winerrno) |
7
cc592295900f
Add write protocol support for private.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff
changeset
|
14 |
1222
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
15 def kill(pid, logfn, tryhard=True): |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
16 logfn('# Killing daemon process %d' % pid) |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
17 PROCESS_TERMINATE = 1 |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
18 PROCESS_QUERY_INFORMATION = 0x400 |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
19 SYNCHRONIZE = 0x00100000 |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
20 WAIT_OBJECT_0 = 0 |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
21 WAIT_TIMEOUT = 258 |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
22 handle = ctypes.windll.kernel32.OpenProcess( |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
23 PROCESS_TERMINATE|SYNCHRONIZE|PROCESS_QUERY_INFORMATION, |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
24 False, pid) |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
25 if handle == 0: |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
26 _check(0, 87) # err 87 when process not found |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
27 return # process not found, already finished |
7
cc592295900f
Add write protocol support for private.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff
changeset
|
28 try: |
1222
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
29 r = ctypes.windll.kernel32.WaitForSingleObject(handle, 100) |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
30 if r == WAIT_OBJECT_0: |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
31 pass # terminated, but process handle still available |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
32 elif r == WAIT_TIMEOUT: |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
33 _check(ctypes.windll.kernel32.TerminateProcess(handle, -1)) |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
34 else: |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
35 _check(r) |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
36 |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
37 # TODO?: forcefully kill when timeout |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
38 # and ?shorter waiting time? when tryhard==True |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
39 r = ctypes.windll.kernel32.WaitForSingleObject(handle, 100) |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
40 # timeout = 100 ms |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
41 if r == WAIT_OBJECT_0: |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
42 pass # process is terminated |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
43 elif r == WAIT_TIMEOUT: |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
44 logfn('# Daemon process %d is stuck') |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
45 else: |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
46 _check(r) # any error |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
47 except: #re-raises |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
48 ctypes.windll.kernel32.CloseHandle(handle) # no _check, keep error |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
49 raise |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
50 _check(ctypes.windll.kernel32.CloseHandle(handle)) |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
51 |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
52 else: |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
53 def kill(pid, logfn, tryhard=True): |
7
cc592295900f
Add write protocol support for private.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff
changeset
|
54 try: |
cc592295900f
Add write protocol support for private.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff
changeset
|
55 os.kill(pid, 0) |
1222
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
56 logfn('# Killing daemon process %d' % pid) |
7
cc592295900f
Add write protocol support for private.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff
changeset
|
57 os.kill(pid, signal.SIGTERM) |
1222
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
58 if tryhard: |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
59 for i in range(10): |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
60 time.sleep(0.05) |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
61 os.kill(pid, 0) |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
62 else: |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
63 time.sleep(0.1) |
7
cc592295900f
Add write protocol support for private.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff
changeset
|
64 os.kill(pid, 0) |
1222
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
65 logfn('# Daemon process %d is stuck - really killing it' % pid) |
7
cc592295900f
Add write protocol support for private.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff
changeset
|
66 os.kill(pid, signal.SIGKILL) |
cc592295900f
Add write protocol support for private.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff
changeset
|
67 except OSError, err: |
cc592295900f
Add write protocol support for private.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff
changeset
|
68 if err.errno != errno.ESRCH: |
cc592295900f
Add write protocol support for private.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff
changeset
|
69 raise |
1222
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
70 |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
71 def killdaemons(pidfile, tryhard=True, remove=False, logfn=None): |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
72 if not logfn: |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
73 logfn = lambda s: s |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
74 # Kill off any leftover daemon processes |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
75 try: |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
76 fp = open(pidfile) |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
77 for line in fp: |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
78 try: |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
79 pid = int(line) |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
80 except ValueError: |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
81 continue |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
82 kill(pid, logfn, tryhard) |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
83 fp.close() |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
84 if remove: |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
85 os.unlink(pidfile) |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
86 except IOError: |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
87 pass |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
88 |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
89 if __name__ == '__main__': |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
90 path, = sys.argv[1:] |
88e61e45026d
tests: import killdaemons.py from Mercurial 1cfded2fa1a9
Matt Harbison <matt_harbison@yahoo.com>
parents:
7
diff
changeset
|
91 killdaemons(path) |