aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2018-04-29 14:09:59 -0700
committerZac Medico <zmedico@gentoo.org>2018-04-29 14:26:37 -0700
commitb530e4e67b843837093e545cf81fd4ab8336d2c2 (patch)
tree5083aaad9c843d08ec354ab32f61a3a1a8fd7a41
parentMergeProcess: fix deprecated _set_returncode (bug 654276) (diff)
downloadportage-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.py58
-rw-r--r--pym/portage/util/_async/PopenProcess.py20
-rw-r--r--pym/portage/util/_async/SchedulerInterface.py1
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",