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..15d0846261b761366dfd3a1183f2536e3ce90473 100644 |
| --- a/scripts/slave/recipe_modules/goma/resources/cloudtail_utils.py |
| +++ b/scripts/slave/recipe_modules/goma/resources/cloudtail_utils.py |
| @@ -54,44 +54,86 @@ class NotDiedError(Exception): |
| return "NotDiedError" |
| -def wait_termination(pid): |
| - """Send SIGINT to pid and wait termination of pid. |
| +class Error(Exception): |
| + """Raised on something unexpected situation.""" |
| + |
| + |
| +def wait_termination_win(pid): |
| + """Send CTRL_C_EVENT or SIGINT to pid and wait termination of pid. |
| Args: |
| pid(int): pid of process which this function waits termination. |
| - Raises: |
| - OSError: is_running_posix, os.waitpid and os.kill may throw OSError. |
| - NotDiedError: if cloudtail is running after 10 seconds waiting, |
| - NotDiedError is raised. |
| + Returns: |
| + None: if pid has already finished or process finished succesfully. |
| + instance of Exception: if raised unexpectedly. |
| """ |
| - |
| + import win32api |
| + import win32con |
| + import win32event |
| + import winerror |
| + import pywintypes |
| + handle = None |
| try: |
| - os.kill(pid, signal.SIGINT) |
| + handle = win32api.OpenProcess( |
| + 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[0] == winerror.ERROR_INVALID_PARAMETER: |
| + os.kill(pid, signal.SIGINT) |
| + print('SIGINT has been sent to process %d.' % pid) |
| + ret = win32event.WaitForSingleObject(handle) |
|
Vadim Sh.
2016/10/26 01:21:16
I think you forgot to specify timeout here.
Yoshisato Yanagisawa
2016/10/26 01:23:14
good catch.
|
| + if ret == win32event.WAIT_TIMEOUT: |
| + raise NotDiedError() |
| + elif ret == win32event.WAIT_OBJECT_0: |
| + return |
| + raise Error('Unexpected return code %d for pid %d.' % (ret, pid)) |
| + except pywintypes.error as e: |
| + if e[0] == winerror.ERROR_INVALID_PARAMETER and e[1] == 'OpenProcess': |
| + print('Can\'t open process %d. Already dead? error %d.' % (pid, e)) |
| + return |
| + raise |
| 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 |
| + finally: |
| + if handle: |
| + win32api.CloseHandle(handle) |
| + |
| - print('SIGINT has been sent to process %d. ' |
| - 'Going to wait for the process finishes.' % pid) |
| +def wait_termination(pid): |
| + """Send SIGINT to pid and wait termination of pid. |
| + |
| + Args: |
| + pid(int): pid of process which this function waits termination. |
| + |
| + Raises: |
| + OSError: is_running_posix, os.waitpid and os.kill may throw OSError. |
| + NotDiedError: if cloudtail is running after 10 seconds waiting, |
| + NotDiedError is raised. |
| + """ |
| if os.name == 'nt': |
| + wait_termination_win(pid) |
| + else: |
| try: |
| - os.waitpid(pid, 0) |
| + 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() |
| @@ -127,7 +169,7 @@ def main(): |
| pid = int(f.read()) |
| try: |
| wait_termination(pid) |
| - except (OSError, NotDiedError) as e: |
| + except Exception as e: |
| print('Going to send SIGTERM to process %d due to Error %s' % (pid, e)) |
| # Since Windows does not have SIGKILL, we need to use SIGTERM. |
| try: |