diff options
author | Zac Medico <zmedico@gentoo.org> | 2018-04-29 14:09:59 -0700 |
---|---|---|
committer | Zac Medico <zmedico@gentoo.org> | 2018-04-29 14:26:37 -0700 |
commit | b530e4e67b843837093e545cf81fd4ab8336d2c2 (patch) | |
tree | 5083aaad9c843d08ec354ab32f61a3a1a8fd7a41 | |
parent | MergeProcess: fix deprecated _set_returncode (bug 654276) (diff) | |
download | portage-b530e4e6.tar.gz portage-b530e4e6.tar.bz2 portage-b530e4e6.zip |
SubProcess: add_child_handler asyncio compat (bug 654276)
Migrate to asyncio's AbstractChildWatcher.add_child_handler
interface. Re-use PopenProcess code introduced in commit
be800bf0153a28ce034277d103a2021f93ac8b2e. Also remove the
child_watch_add method from SchedulerInterface, since there
are no more consumers.
Bug: https://bugs.gentoo.org/654276
-rw-r--r-- | pym/_emerge/SubProcess.py | 58 | ||||
-rw-r--r-- | pym/portage/util/_async/PopenProcess.py | 20 | ||||
-rw-r--r-- | pym/portage/util/_async/SchedulerInterface.py | 1 |
3 files changed, 11 insertions, 68 deletions
diff --git a/pym/_emerge/SubProcess.py b/pym/_emerge/SubProcess.py index 3939de3ed..aa4778737 100644 --- a/pym/_emerge/SubProcess.py +++ b/pym/_emerge/SubProcess.py @@ -19,28 +19,7 @@ class SubProcess(AbstractPollTask): _cancel_timeout = 1000 # 1 second def _poll(self): - if self.returncode is not None: - return self.returncode - if self.pid is None: - return self.returncode - if self._registered: - return self.returncode - - try: - # With waitpid and WNOHANG, only check the - # first element of the tuple since the second - # element may vary (bug #337465). - retval = os.waitpid(self.pid, os.WNOHANG) - except OSError as e: - if e.errno != errno.ECHILD: - raise - del e - retval = (self.pid, 1) - - if retval[0] == 0: - return None - self._set_returncode(retval) - self._async_wait() + # Simply rely on _async_waitpid_cb to set the returncode. return self.returncode def _cancel(self): @@ -71,20 +50,16 @@ class SubProcess(AbstractPollTask): if self.returncode is not None: self._async_wait() elif self._waitpid_id is None: - self._waitpid_id = self.scheduler.child_watch_add( - self.pid, self._async_waitpid_cb) + self._waitpid_id = self.pid + self.scheduler._asyncio_child_watcher.\ + add_child_handler(self.pid, self._async_waitpid_cb) - def _async_waitpid_cb(self, pid, condition, user_data=None): + def _async_waitpid_cb(self, pid, returncode): if pid != self.pid: raise AssertionError("expected pid %s, got %s" % (self.pid, pid)) - self._set_returncode((pid, condition)) + self.returncode = returncode self._async_wait() - def _waitpid_cb(self, pid, condition, user_data=None): - if pid != self.pid: - raise AssertionError("expected pid %s, got %s" % (self.pid, pid)) - self._set_returncode((pid, condition)) - def _orphan_process_warn(self): pass @@ -100,7 +75,8 @@ class SubProcess(AbstractPollTask): self._reg_id = None if self._waitpid_id is not None: - self.scheduler.source_remove(self._waitpid_id) + self.scheduler._asyncio_child_watcher.\ + remove_child_handler(self._waitpid_id) self._waitpid_id = None if self._files is not None: @@ -126,21 +102,3 @@ class SubProcess(AbstractPollTask): elif event & self.scheduler.IO_HUP: self._unregister() self._async_waitpid() - - def _set_returncode(self, wait_retval): - """ - Set the returncode in a manner compatible with - subprocess.Popen.returncode: A negative value -N indicates - that the child was terminated by signal N (Unix only). - """ - self._unregister() - - pid, status = wait_retval - - if os.WIFSIGNALED(status): - retval = - os.WTERMSIG(status) - else: - retval = os.WEXITSTATUS(status) - - self.returncode = retval - diff --git a/pym/portage/util/_async/PopenProcess.py b/pym/portage/util/_async/PopenProcess.py index 3fb60d527..c1931327a 100644 --- a/pym/portage/util/_async/PopenProcess.py +++ b/pym/portage/util/_async/PopenProcess.py @@ -25,23 +25,9 @@ class PopenProcess(SubProcess): def _pipe_reader_exit(self, pipe_reader): self._async_waitpid() - def _async_waitpid(self): - if self.returncode is None: - self.scheduler._asyncio_child_watcher.\ - add_child_handler(self.pid, self._async_waitpid_cb) - else: - self._unregister() - self._async_wait() - - def _async_waitpid_cb(self, pid, returncode): + def _async_waitpid_cb(self, *args, **kwargs): + SubProcess._async_waitpid_cb(self, *args, **kwargs) if self.proc.returncode is None: # Suppress warning messages like this: # ResourceWarning: subprocess 1234 is still running - self.proc.returncode = returncode - self._unregister() - self.returncode = returncode - self._async_wait() - - def _poll(self): - # Simply rely on _async_waitpid_cb to set the returncode. - return self.returncode + self.proc.returncode = self.returncode diff --git a/pym/portage/util/_async/SchedulerInterface.py b/pym/portage/util/_async/SchedulerInterface.py index be118ae0e..ff39bc587 100644 --- a/pym/portage/util/_async/SchedulerInterface.py +++ b/pym/portage/util/_async/SchedulerInterface.py @@ -13,7 +13,6 @@ class SchedulerInterface(SlotObject): _event_loop_attrs = ("IO_ERR", "IO_HUP", "IO_IN", "IO_NVAL", "IO_OUT", "IO_PRI", - "child_watch_add", "io_add_watch", "source_remove", "timeout_add", |