Chromium Code Reviews| Index: scripts/slave/recipe_modules/goma/resources/cloudtail_utils.py |
| diff --git a/scripts/slave/recipe_modules/goma/resources/cloudtail_utils.py b/scripts/slave/recipe_modules/goma/resources/cloudtail_utils.py |
| index bfe97d81c9b55bf1b895a97ad565957f9d21e63d..ee7fb352920f96a26936d32f15b99b3c2c20cdb4 100644 |
| --- a/scripts/slave/recipe_modules/goma/resources/cloudtail_utils.py |
| +++ b/scripts/slave/recipe_modules/goma/resources/cloudtail_utils.py |
| @@ -5,6 +5,7 @@ |
| import argparse |
| import errno |
| +import multiprocessing |
| import os |
| import signal |
| import subprocess |
| @@ -54,6 +55,39 @@ class NotDiedError(Exception): |
| return "NotDiedError" |
| +def wait_termination_win(pid): |
|
ukai
2016/10/25 07:30:24
doc string?
Yoshisato Yanagisawa
2016/10/25 07:48:20
Done.
|
| + import win32api |
| + import win32con |
| + import pywintypes |
| + try: |
| + handle = win32api.OpenProcess( |
|
ukai
2016/10/25 07:30:24
no need to close the handle?
Yoshisato Yanagisawa
2016/10/25 07:48:20
Done.
|
| + win32con.PROCESS_QUERY_INFORMATION | win32con.SYNCHRONIZE, |
| + False, pid) |
| + try: |
| + os.kill(pid, signal.CTRL_C_EVENT) |
| + print('CTRL_C_EVENT has been sent to process %d. ' |
| + 'Going to wait for the process finishes.' % pid) |
| + except WindowsError as e: # pylint: disable=E0602 |
| + # If a target process does not share terminal, we cannot send Ctrl-C. |
| + if e.errno == 87: # 87 == invalid parameter |
| + os.kill(pid, signal.SIGINT) |
| + os.waitpid(handle, 0) |
| + return None |
| + except pywintypes.error as e: |
| + if e[0] == 87 and e[1] == 'OpenProcess': |
| + print('Can\'t open process %d. Already dead? error %d.' % (pid, e)) |
| + return None |
| + raise |
| + except OSError as e: |
| + if e.errno in (errno.ECHILD, errno.EPERM, errno.ESRCH): |
| + print('Can\'t send SIGINT to process %d. Already dead? Errno %d.' % |
| + (pid, e.errno)) |
| + return None |
| + raise |
| + except Exception as e: |
| + return e |
| + |
| + |
| def wait_termination(pid): |
| """Send SIGINT to pid and wait termination of pid. |
| @@ -65,33 +99,29 @@ def wait_termination(pid): |
| NotDiedError: if cloudtail is running after 10 seconds waiting, |
| NotDiedError is raised. |
| """ |
| - |
| - try: |
| - os.kill(pid, signal.SIGINT) |
| - except OSError as e: |
| - # Already dead? |
| - if e.errno in (errno.ECHILD, errno.EPERM, errno.ESRCH): |
| - print('Can\'t send SIGINT to process %d. Already dead? Errno %d.' % |
| - (pid, e.errno)) |
| - return |
| - raise |
| - |
| - print('SIGINT has been sent to process %d. ' |
| - 'Going to wait for the process finishes.' % pid) |
| if os.name == 'nt': |
| + pool = multiprocessing.Pool(1) |
| + res = pool.apply_async(wait_termination_win, [pid]) |
| try: |
| - os.waitpid(pid, 0) |
| + e = res.get(10) |
| + except multiprocessing.TimeoutError: |
| + print('process %d running more than 10 seconds.' % pid) |
| + raise NotDiedError() |
| + if e is None: |
| + return |
| + raise e |
| + else: |
| + try: |
| + os.kill(pid, signal.SIGINT) |
| except OSError as e: |
| - if e.errno == errno.ECHILD: |
| - print('process %d died before waitpitd' % pid) |
| + if e.errno in (errno.ECHILD, errno.EPERM, errno.ESRCH): |
| + print('Can\'t send SIGINT to process %d. Already dead? Errno %d.' % |
| + (pid, e.errno)) |
| return |
| - raise e |
| - else: |
| for _ in xrange(10): |
| time.sleep(1) |
| if not is_running_posix(pid): |
| return |
| - |
| print('process %d running more than 10 seconds' % pid) |
| raise NotDiedError() |