22
27
from twisted.application import service
23
28
from twisted.python import log
30
# This file is used by launchpad-buildd, so it cannot import any
34
def two_stage_kill(pid, poll_interval=0.1, num_polls=50):
35
"""Kill process 'pid' with SIGTERM. If it doesn't die, SIGKILL it.
37
:param pid: The pid of the process to kill.
38
:param poll_interval: The polling interval used to check if the
39
process is still around.
40
:param num_polls: The number of polls to do before doing a SIGKILL.
46
if e.errno in (errno.ESRCH, errno.ECHILD):
47
# Process has already been killed.
50
# Poll until the process has ended.
51
for i in range(num_polls):
53
# Reap the child process and get its return value. If it's not
55
new_pid, result = os.waitpid(pid, os.WNOHANG)
58
time.sleep(poll_interval)
60
if e.errno in (errno.ESRCH, errno.ECHILD):
61
# Raised if the process is gone by the time we try to get the
65
# The process is still around, so terminate it violently.
73
def kill_by_pidfile(pidfile_path):
74
"""Kill a process identified by the pid stored in a file.
76
The pid file is removed from disk.
78
if not os.path.exists(pidfile_path):
82
pid = open(pidfile_path, 'r').read().split()[0]
86
# pidfile contains rubbish
91
remove_if_exists(pidfile_path)
94
def remove_if_exists(path):
95
"""Remove the given file if it exists."""
99
if e.errno != errno.ENOENT:
26
103
twistd_script = os.path.abspath(os.path.join(
27
104
os.path.dirname(__file__),
48
125
# started. If it sees an old logfile, then it will find the LOG_MAGIC
49
126
# string and return immediately, provoking hard-to-diagnose race
50
127
# conditions. Delete the logfile to make sure this does not happen.
51
self._removeFile(self.logfile)
128
remove_if_exists(self.logfile)
54
131
args = [sys.executable, twistd_script, '-o', '-y', self.tacfile,
107
184
def tearDown(self):
110
def _removeFile(self, filename):
111
"""Remove the given file if it exists."""
115
if e.errno != errno.ENOENT:
118
187
def killTac(self):
119
188
"""Kill the TAC file if it is running."""
120
189
pidfile = self.pidfile
121
if not os.path.exists(pidfile):
125
pid = open(pidfile, 'r').read().strip()
129
# pidfile contains rubbish
134
os.kill(pid, SIGTERM)
136
if e.errno in (errno.ESRCH, errno.ECHILD):
137
# Process has already been killed.
140
# Poll until the process has ended.
148
# The process is still around, so terminate it violently.
150
os.kill(pid, SIGKILL)
190
kill_by_pidfile(pidfile)
155
192
def setUpRoot(self):
156
193
"""Override this.