remove workaround for Python bug in asyncio process.wait(). Requires Python 3.5. Closes #58

This commit is contained in:
Sebastien Bourdeauducq 2015-10-03 14:33:18 +08:00
parent 4b2a99b090
commit 125503139e
6 changed files with 17 additions and 42 deletions

View File

@ -11,7 +11,7 @@ import socket
from artiq.protocols.sync_struct import Subscriber from artiq.protocols.sync_struct import Subscriber
from artiq.protocols.pc_rpc import AsyncioClient, Server from artiq.protocols.pc_rpc import AsyncioClient, Server
from artiq.tools import verbosity_args, init_logger from artiq.tools import verbosity_args, init_logger
from artiq.tools import TaskObject, asyncio_process_wait_timeout, Condition from artiq.tools import TaskObject, Condition
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -88,8 +88,8 @@ class Controller:
def _wait_and_ping(self): def _wait_and_ping(self):
while True: while True:
try: try:
yield from asyncio_process_wait_timeout(self.process, yield from asyncio.wait_for(self.process.wait(),
self.ping_timer) self.ping_timer)
except asyncio.TimeoutError: except asyncio.TimeoutError:
logger.debug("pinging controller %s", self.name) logger.debug("pinging controller %s", self.name)
ok = yield from self._ping() ok = yield from self._ping()
@ -137,8 +137,8 @@ class Controller:
"command, killing", self.name) "command, killing", self.name)
self.process.kill() self.process.kill()
try: try:
yield from asyncio_process_wait_timeout(self.process, yield from asyncio.wait_for(self.process.wait(),
self.term_timeout) self.term_timeout)
except: except:
logger.warning("Controller %s failed to exit, killing", logger.warning("Controller %s failed to exit, killing",
self.name) self.name)

View File

@ -7,8 +7,7 @@ import time
from functools import partial from functools import partial
from artiq.protocols import pyon from artiq.protocols import pyon
from artiq.tools import (asyncio_process_wait_timeout, asyncio_process_wait, from artiq.tools import asyncio_wait_or_cancel
asyncio_wait_or_cancel)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -97,15 +96,14 @@ class Worker:
logger.warning("failed to send terminate command to worker" logger.warning("failed to send terminate command to worker"
" (RID %s), killing", self.rid, exc_info=True) " (RID %s), killing", self.rid, exc_info=True)
self.process.kill() self.process.kill()
yield from asyncio_process_wait(self.process) yield from self.process.wait()
return return
try: try:
yield from asyncio_process_wait_timeout(self.process, yield from asyncio.wait_for(self.process.wait(), term_timeout)
term_timeout)
except asyncio.TimeoutError: except asyncio.TimeoutError:
logger.warning("worker did not exit (RID %s), killing", self.rid) logger.warning("worker did not exit (RID %s), killing", self.rid)
self.process.kill() self.process.kill()
yield from asyncio_process_wait(self.process) yield from self.process.wait()
else: else:
logger.debug("worker exited gracefully (RID %s)", self.rid) logger.debug("worker exited gracefully (RID %s)", self.rid)
finally: finally:

View File

@ -88,29 +88,6 @@ def exc_to_warning(coro):
exc_info=True) exc_info=True)
@asyncio.coroutine
def asyncio_process_wait_timeout(process, timeout):
# In Python < 3.5, asyncio.wait_for(process.wait(), ...
# causes a futures.InvalidStateError inside asyncio if and when the
# process terminates after the timeout.
# Work around this problem.
@asyncio.coroutine
def process_wait_returncode_timeout():
while True:
if process.returncode is not None:
break
yield from asyncio.sleep(0.1)
yield from asyncio.wait_for(process_wait_returncode_timeout(),
timeout=timeout)
@asyncio.coroutine
def asyncio_process_wait(process):
r = True
while r:
f, p = yield from asyncio.wait([process.stdout.read(1024)])
r = f.pop().result()
@asyncio.coroutine @asyncio.coroutine
def asyncio_wait_or_cancel(fs, **kwargs): def asyncio_wait_or_cancel(fs, **kwargs):
fs = [asyncio.async(f) for f in fs] fs = [asyncio.async(f) for f in fs]

View File

@ -28,14 +28,14 @@ build:
requirements: requirements:
build: build:
- python >=3.4.4 - python >=3.5.0
- setuptools - setuptools
- numpy - numpy
- migen - migen
- pyelftools - pyelftools
- binutils-or1k-linux - binutils-or1k-linux
run: run:
- python >=3.4.4 - python >=3.5.0
- llvmlite-artiq - llvmlite-artiq
- scipy - scipy
- numpy - numpy

View File

@ -13,9 +13,9 @@ Installing using conda
Installing Anaconda or Miniconda Installing Anaconda or Miniconda
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* You can either install Anaconda (chose Python 3.4) from https://store.continuum.io/cshop/anaconda/ * You can either install Anaconda (chose Python 3.5) from https://store.continuum.io/cshop/anaconda/
* Or install the more minimalistic Miniconda (chose Python 3.4) from http://conda.pydata.org/miniconda.html * Or install the more minimalistic Miniconda (chose Python 3.5) from http://conda.pydata.org/miniconda.html
.. warning:: .. warning::
If you are installing on Windows, chose the Windows 32-bit version regardless of whether you have If you are installing on Windows, chose the Windows 32-bit version regardless of whether you have
@ -148,7 +148,7 @@ These steps are required to generate bitstream (``.bit``) files, build the MiSoC
$ python3 setup.py develop --user $ python3 setup.py develop --user
.. note:: .. note::
The options ``develop`` and ``--user`` are for setup.py to install Migen in ``~/.local/lib/python3.4``. The options ``develop`` and ``--user`` are for setup.py to install Migen in ``~/.local/lib/python3.5``.
.. _install-xc3sprog: .. _install-xc3sprog:
@ -369,7 +369,7 @@ This command installs all the required packages: ::
$ sudo apt-get install build-essential autotools-dev file git patch perl xutils-dev python3-pip texinfo flex bison libmpc-dev python3-serial python3-dateutil python3-prettytable python3-setuptools python3-numpy python3-scipy python3-sphinx python3-h5py python3-dev python-dev subversion cmake libusb-dev libftdi-dev pkg-config libffi-dev libgit2-dev $ sudo apt-get install build-essential autotools-dev file git patch perl xutils-dev python3-pip texinfo flex bison libmpc-dev python3-serial python3-dateutil python3-prettytable python3-setuptools python3-numpy python3-scipy python3-sphinx python3-h5py python3-dev python-dev subversion cmake libusb-dev libftdi-dev pkg-config libffi-dev libgit2-dev
Note that ARTIQ requires Python 3.4.4 or above. Note that ARTIQ requires Python 3.5.0 or above.
To set user permissions on the JTAG and serial ports of the Pipistrello, create a ``/etc/udev/rules.d/30-usb-papilio.rules`` file containing the following: :: To set user permissions on the JTAG and serial ports of the Pipistrello, create a ``/etc/udev/rules.d/30-usb-papilio.rules`` file containing the following: ::

View File

@ -5,8 +5,8 @@ import sys
import os import os
if sys.version_info[:3] < (3, 4, 4): if sys.version_info[:3] < (3, 5, 0):
raise Exception("You need Python 3.4.4+") raise Exception("You need Python 3.5.0+")
class PushDocCommand(Command): class PushDocCommand(Command):