diff options
author | Zac Medico <zmedico@gentoo.org> | 2012-02-16 12:58:29 -0800 |
---|---|---|
committer | Zac Medico <zmedico@gentoo.org> | 2012-02-16 12:59:17 -0800 |
commit | 1979a6cdfcd8c6bae4565982d82d862be07ba5be (patch) | |
tree | 544a5dc31cea629aaf79b4a097306e7dc5d197bf | |
parent | 0166ba48b976f7e7262f59df0b3d0b499d0f2a63 (diff) | |
download | portage-1979a6cdfcd8c6bae4565982d82d862be07ba5be.tar.gz portage-1979a6cdfcd8c6bae4565982d82d862be07ba5be.tar.bz2 portage-1979a6cdfcd8c6bae4565982d82d862be07ba5be.zip |
SubProcess: use child_watch_add
This fixes performance issues introduced by commit
9c664779a16f6cbca8a5ffe7f6b0c68572819723.
-rw-r--r-- | pym/_emerge/SubProcess.py | 36 |
1 files changed, 7 insertions, 29 deletions
diff --git a/pym/_emerge/SubProcess.py b/pym/_emerge/SubProcess.py index 01004a874..9c033c562 100644 --- a/pym/_emerge/SubProcess.py +++ b/pym/_emerge/SubProcess.py @@ -20,9 +20,6 @@ class SubProcess(AbstractPollTask): # we've sent a kill signal to our subprocess. _cancel_timeout = 1000 # 1 second - # Poll interval for process exit status. - _waitpid_interval = 1000 # 1 second - def _poll(self): if self.returncode is not None: return self.returncode @@ -95,37 +92,18 @@ class SubProcess(AbstractPollTask): return self.returncode def _waitpid_loop(self): - if not self._waitpid_cb(): - return - - timeout_id = self.scheduler.timeout_add( - self._waitpid_interval, self._waitpid_cb) + source_id = self.scheduler.child_watch_add( + self.pid, self._waitpid_cb) try: while self.returncode is None: self.scheduler.iteration() finally: - self.scheduler.source_remove(timeout_id) - - def _waitpid_cb(self): - if self.returncode is not None: - return False - try: - # With waitpid and WNOHANG, only check the - # first element of the tuple since the second - # element may vary (bug #337465). - wait_retval = os.waitpid(self.pid, os.WNOHANG) - except OSError as e: - if e.errno != errno.ECHILD: - raise - del e - self._set_returncode((self.pid, 1 << 8)) - return False - else: - if wait_retval[0] != 0: - self._set_returncode(wait_retval) - return False + self.scheduler.source_remove(source_id) - return True + def _waitpid_cb(self, pid, condition, user_data): + 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 |