mirror of
https://github.com/GNS3/gns3-server
synced 2024-11-24 17:28:08 +00:00
Fix a crash with Python 3.4 when you stop IOU
http://bugs.python.org/issue23140
This commit is contained in:
parent
aa40e6097e
commit
5a58f6efc8
@ -483,18 +483,19 @@ class IOUVM(BaseVM):
|
||||
self._ioucon_thread = None
|
||||
|
||||
self._terminate_process_iou()
|
||||
try:
|
||||
yield from asyncio.wait_for(self._iou_process.wait(), timeout=3)
|
||||
except asyncio.TimeoutError:
|
||||
self._iou_process.kill()
|
||||
if self._iou_process.returncode is None:
|
||||
log.warn("IOU process {} is still running".format(self._iou_process.pid))
|
||||
if self._iou_process.returncode is None:
|
||||
try:
|
||||
yield from gns3server.utils.asyncio.wait_for_process_termination(self._iou_process, timeout=3)
|
||||
except asyncio.TimeoutError:
|
||||
self._iou_process.kill()
|
||||
if self._iou_process.returncode is None:
|
||||
log.warn("IOU process {} is still running".format(self._iou_process.pid))
|
||||
self._iou_process = None
|
||||
|
||||
if self._iouyap_process is not None:
|
||||
self._terminate_process_iouyap()
|
||||
try:
|
||||
yield from asyncio.wait_for(self._iouyap_process.wait(), timeout=3)
|
||||
yield from gns3server.utils.asyncio.wait_for_process_termination(self._iouyap_process, timeout=3)
|
||||
except asyncio.TimeoutError:
|
||||
self._iouyap_process.kill()
|
||||
if self._iouyap_process.returncode is None:
|
||||
|
@ -53,3 +53,27 @@ def subprocess_check_output(*args, cwd=None, env=None):
|
||||
if output is None:
|
||||
return ""
|
||||
return output.decode("utf-8")
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def wait_for_process_termination(process, timeout=10):
|
||||
"""
|
||||
Wait for a process terminate, and raise asyncio.TimeoutError in case of
|
||||
timeout.
|
||||
|
||||
In theory this can be implemented by just:
|
||||
yield from asyncio.wait_for(self._iou_process.wait(), timeout=100)
|
||||
|
||||
But it's broken before Python 3.4:
|
||||
http://bugs.python.org/issue23140
|
||||
|
||||
:param process: An asyncio subprocess
|
||||
:param timeout: Timeout in seconds
|
||||
"""
|
||||
|
||||
while timeout > 0:
|
||||
if process.returncode is not None:
|
||||
return
|
||||
yield from asyncio.sleep(0.1)
|
||||
timeout -= 0.1
|
||||
raise asyncio.TimeoutError()
|
||||
|
@ -18,8 +18,9 @@
|
||||
|
||||
import asyncio
|
||||
import pytest
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from gns3server.utils.asyncio import wait_run_in_executor, subprocess_check_output
|
||||
from gns3server.utils.asyncio import wait_run_in_executor, subprocess_check_output, wait_for_process_termination
|
||||
|
||||
|
||||
def test_wait_run_in_executor(loop):
|
||||
@ -50,3 +51,17 @@ def test_subprocess_check_output(loop, tmpdir, restore_original_path):
|
||||
exec = subprocess_check_output("cat", path)
|
||||
result = loop.run_until_complete(asyncio.async(exec))
|
||||
assert result == "TEST"
|
||||
|
||||
|
||||
def test_wait_for_process_termination(loop):
|
||||
|
||||
process = MagicMock()
|
||||
process.returncode = 0
|
||||
exec = wait_for_process_termination(process)
|
||||
loop.run_until_complete(asyncio.async(exec))
|
||||
|
||||
process = MagicMock()
|
||||
process.returncode = None
|
||||
exec = wait_for_process_termination(process, timeout=0.5)
|
||||
with pytest.raises(asyncio.TimeoutError):
|
||||
loop.run_until_complete(asyncio.async(exec))
|
||||
|
Loading…
Reference in New Issue
Block a user