diff --git a/homeassistant/__main__.py b/homeassistant/__main__.py index af89564f102..91b7a7f8466 100644 --- a/homeassistant/__main__.py +++ b/homeassistant/__main__.py @@ -19,15 +19,19 @@ from homeassistant.const import ( ) -def attempt_use_uvloop() -> None: +def set_loop() -> None: """Attempt to use uvloop.""" import asyncio - try: - import uvloop - except ImportError: - pass + + if sys.platform == 'win32': + asyncio.set_event_loop(asyncio.ProactorEventLoop()) else: - asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) + try: + import uvloop + except ImportError: + pass + else: + asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) def validate_python() -> None: @@ -244,17 +248,6 @@ async def setup_and_run_hass(config_dir: str, """Set up HASS and run.""" from homeassistant import bootstrap, core - # Run a simple daemon runner process on Windows to handle restarts - if os.name == 'nt' and '--runner' not in sys.argv: - nt_args = cmdline() + ['--runner'] - while True: - try: - subprocess.check_call(nt_args) - sys.exit(0) - except subprocess.CalledProcessError as exc: - if exc.returncode != RESTART_EXIT_CODE: - sys.exit(exc.returncode) - hass = core.HomeAssistant() if args.demo_mode: @@ -345,7 +338,20 @@ def main() -> int: monkey_patch.disable_c_asyncio() monkey_patch.patch_weakref_tasks() - attempt_use_uvloop() + set_loop() + + # Run a simple daemon runner process on Windows to handle restarts + if os.name == 'nt' and '--runner' not in sys.argv: + nt_args = cmdline() + ['--runner'] + while True: + try: + subprocess.check_call(nt_args) + sys.exit(0) + except KeyboardInterrupt: + sys.exit(0) + except subprocess.CalledProcessError as exc: + if exc.returncode != RESTART_EXIT_CODE: + sys.exit(exc.returncode) args = get_arguments() diff --git a/homeassistant/core.py b/homeassistant/core.py index 653f95ccece..d1f811502e0 100644 --- a/homeassistant/core.py +++ b/homeassistant/core.py @@ -129,10 +129,7 @@ class HomeAssistant: self, loop: Optional[asyncio.events.AbstractEventLoop] = None) -> None: """Initialize new Home Assistant object.""" - if sys.platform == 'win32': - self.loop = loop or asyncio.ProactorEventLoop() - else: - self.loop = loop or asyncio.get_event_loop() + self.loop = loop or asyncio.get_event_loop() executor_opts = {'max_workers': None} # type: Dict[str, Any] if sys.version_info[:2] >= (3, 6): diff --git a/homeassistant/helpers/signal.py b/homeassistant/helpers/signal.py index 6068cad33af..7496388fb52 100644 --- a/homeassistant/helpers/signal.py +++ b/homeassistant/helpers/signal.py @@ -43,3 +43,28 @@ def async_register_signal_handling(hass: HomeAssistant) -> None: signal.SIGHUP, async_signal_handle, RESTART_EXIT_CODE) except ValueError: _LOGGER.warning("Could not bind to SIGHUP") + + else: + old_sigterm = None + old_sigint = None + + @callback + def async_signal_handle(exit_code, frame): + """Wrap signal handling. + + * queue call to shutdown task + * re-instate default handler + """ + signal.signal(signal.SIGTERM, old_sigterm) + signal.signal(signal.SIGINT, old_sigint) + hass.async_create_task(hass.async_stop(exit_code)) + + try: + old_sigterm = signal.signal(signal.SIGTERM, async_signal_handle) + except ValueError: + _LOGGER.warning("Could not bind to SIGTERM") + + try: + old_sigint = signal.signal(signal.SIGINT, async_signal_handle) + except ValueError: + _LOGGER.warning("Could not bind to SIGINT")