##// END OF EJS Templates
Work around lack of os.kill in win32....
Bradley M. Froehle -
Show More
@@ -328,8 +328,8 b' class IPTester(object):'
328 params = None
328 params = None
329 #: list, arguments of system call to be made to call test runner
329 #: list, arguments of system call to be made to call test runner
330 call_args = None
330 call_args = None
331 #: list, process ids of subprocesses we start (for cleanup)
331 #: list, subprocesses we start (for cleanup)
332 pids = None
332 processes = None
333 #: str, coverage xml output file
333 #: str, coverage xml output file
334 coverage_xml = None
334 coverage_xml = None
335
335
@@ -370,19 +370,18 b' class IPTester(object):'
370 self.call_args.remove('--with-xml-coverage')
370 self.call_args.remove('--with-xml-coverage')
371 self.call_args = ["coverage", "run", "--source="+sect] + self.call_args[1:]
371 self.call_args = ["coverage", "run", "--source="+sect] + self.call_args[1:]
372
372
373 # Store pids of anything we start to clean up on deletion, if possible
373 # Store anything we start to clean up on deletion
374 # (on posix only, since win32 has no os.kill)
374 self.processes = []
375 self.pids = []
376
375
377 def _run_cmd(self):
376 def _run_cmd(self):
378 # print >> sys.stderr, '*** CMD:', ' '.join(self.call_args) # dbg
377 # print >> sys.stderr, '*** CMD:', ' '.join(self.call_args) # dbg
379 subp = subprocess.Popen(self.call_args)
378 subp = subprocess.Popen(self.call_args)
380 self.pids.append(subp.pid)
379 self.processes.append(subp)
381 # If this fails, the pid will be left in self.pids and cleaned up
380 # If this fails, the process will be left in self.processes and cleaned
382 # later, but if the wait call succeeds, then we can clear the
381 # up later, but if the wait call succeeds, then we can clear the
383 # stored pid.
382 # stored process.
384 retcode = subp.wait()
383 retcode = subp.wait()
385 self.pids.pop()
384 self.processes.pop()
386 return retcode
385 return retcode
387
386
388 def run(self):
387 def run(self):
@@ -398,28 +397,13 b' class IPTester(object):'
398 subprocess.call(["coverage", "xml", "-o", self.coverage_xml])
397 subprocess.call(["coverage", "xml", "-o", self.coverage_xml])
399 return retcode
398 return retcode
400
399
401 @staticmethod
402 def _kill(pid):
403 """Attempt to kill the process on a best effort basis."""
404 if hasattr(os, 'kill'):
405 os.kill(pid, signal.SIGKILL)
406 elif sys.platform == 'win32':
407 # Python 2.6 on Windows doesn't have os.kill.
408 from ctypes import windll
409 PROCESS_TERMINATE = 1
410 handle = windll.kernel32.OpenProcess(PROCESS_TERMINATE, False, pid)
411 windll.kernel32.TerminateProcess(handle, -1)
412 windll.kernel32.CloseHandle(handle)
413 else:
414 raise NotImplementedError
415
416 def __del__(self):
400 def __del__(self):
417 """Cleanup on exit by killing any leftover processes."""
401 """Cleanup on exit by killing any leftover processes."""
418 for pid in self.pids:
402 for subp in self.processes:
419 try:
403 try:
420 print('Cleaning stale PID:', pid)
404 print('Cleaning stale PID: %d' % subp.pid)
421 self._kill(pid)
405 subp.kill()
422 except (OSError, NotImplementedError):
406 except: # (OSError, WindowsError) ?
423 # This is just a best effort, if we fail or the process was
407 # This is just a best effort, if we fail or the process was
424 # really gone, ignore it.
408 # really gone, ignore it.
425 pass
409 pass
General Comments 0
You need to be logged in to leave comments. Login now