Skip to content

Commit

Permalink
signal.SIGKILL doesn’t exist on Windows, so emulate it in our Event
Browse files Browse the repository at this point in the history
  • Loading branch information
wjwwood committed Jun 20, 2018
1 parent e14e644 commit 596aa2e
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 5 deletions.
3 changes: 3 additions & 0 deletions launch/launch/actions/execute_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,9 @@ def __on_signal_process_event(
_logger.info("sending signal '{}' to process[{}]".format(
typed_event.signal_name, self.process_details['name']
))
if typed_event.signal_name == 'SIGKILL':
self._subprocess_transport.kill() # works on both Windows and POSIX
return None
self._subprocess_transport.send_signal(typed_event.signal)
return None

Expand Down
18 changes: 13 additions & 5 deletions launch/launch/events/process/signal_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import signal as signal_module # to avoid confusion with .signal property in type annotations
from typing import Callable
from typing import Text
from typing import Union

from .process_targeted_event import ProcessTargetedEvent
from ...utilities import ensure_argument_type
Expand All @@ -33,23 +34,30 @@ class SignalProcess(ProcessTargetedEvent):

def __init__(
self, *,
signal_number: signal_module.Signals,
signal_number: Union[Text, signal_module.Signals],
process_matcher: Callable[['ExecuteProcess'], bool]
) -> None:
"""
Constructor.
Takes an optional process matcher, which can be used to match the
signal to a process.
Since Windows does not support SIGKILL, the string 'SIGKILL' can be
given instead of `signal.SIGKILL`.
Handlers of this event can then check for the 'SIGKILL' string and do
the appropriate thing on Windows instead of sending a signal.
:signal_number: either the string 'SIGKILL' or a signal.Signals
"""
super().__init__(process_matcher=process_matcher)
ensure_argument_type(
signal_number, (signal_module.Signals,), 'signal_number', 'SignalProcess')
signal_number, (str, signal_module.Signals), 'signal_number', 'SignalProcess')
self.__signal = signal_number

@property
def signal(self) -> signal_module.Signals:
"""Getter for signal, it will match something from the signal module."""
def signal(self) -> Union[Text, signal_module.Signals]:
"""Getter for signal, it will be 'SIGKILL' or match something from the signal module."""
return self.__signal

@property
Expand All @@ -59,4 +67,4 @@ def signal_name(self) -> Text:
It will be something like (e.g.) 'SIGINT'.
"""
return self.__signal.name
return self.__signal if isinstance(self.__signal, str) else self.__signal.name

0 comments on commit 596aa2e

Please sign in to comment.