public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/portage:master commit in: pym/_emerge/, pym/portage/util/_async/
@ 2018-04-29 21:29 Zac Medico
  0 siblings, 0 replies; 2+ messages in thread
From: Zac Medico @ 2018-04-29 21:29 UTC (permalink / raw
  To: gentoo-commits

commit:     b530e4e67b843837093e545cf81fd4ab8336d2c2
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Sun Apr 29 21:09:59 2018 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Sun Apr 29 21:26:37 2018 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=b530e4e6

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

 pym/_emerge/SubProcess.py                     | 58 ++++-----------------------
 pym/portage/util/_async/PopenProcess.py       | 20 ++-------
 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",


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [gentoo-commits] proj/portage:master commit in: pym/_emerge/, pym/portage/util/_async/
@ 2018-04-30  6:29 Zac Medico
  0 siblings, 0 replies; 2+ messages in thread
From: Zac Medico @ 2018-04-30  6:29 UTC (permalink / raw
  To: gentoo-commits

commit:     c11a6ec05f02601a7c2cb5455d1289b9dfed5f10
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Mon Apr 30 06:06:56 2018 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Mon Apr 30 06:24:15 2018 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=c11a6ec0

AbstractPollTask: add_reader asyncio compat (bug 654382)

Migration to add_reader is now complete, so remove unused code related
to io_add_watch (and source_remove).

Bug: https://bugs.gentoo.org/654382

 pym/_emerge/AbstractEbuildProcess.py          |  5 -----
 pym/_emerge/AbstractPollTask.py               | 29 +++++----------------------
 pym/_emerge/PipeReader.py                     |  2 +-
 pym/_emerge/SubProcess.py                     | 22 +-------------------
 pym/portage/util/_async/SchedulerInterface.py |  6 +-----
 5 files changed, 8 insertions(+), 56 deletions(-)

diff --git a/pym/_emerge/AbstractEbuildProcess.py b/pym/_emerge/AbstractEbuildProcess.py
index ccc3b8e32..370cac529 100644
--- a/pym/_emerge/AbstractEbuildProcess.py
+++ b/pym/_emerge/AbstractEbuildProcess.py
@@ -347,11 +347,6 @@ class AbstractEbuildProcess(SpawnProcess):
 				log_path = self.settings.get("PORTAGE_LOG_FILE")
 			self.scheduler.output(msg, log_path=log_path)
 
-	def _log_poll_exception(self, event):
-		self._elog("eerror",
-			["%s received strange poll event: %s\n" % \
-			(self.__class__.__name__, event,)])
-
 	def _async_waitpid_cb(self, *args, **kwargs):
 		"""
 		Override _async_waitpid_cb to perform cleanup that is

diff --git a/pym/_emerge/AbstractPollTask.py b/pym/_emerge/AbstractPollTask.py
index 2c5403751..3a869cb46 100644
--- a/pym/_emerge/AbstractPollTask.py
+++ b/pym/_emerge/AbstractPollTask.py
@@ -44,18 +44,16 @@ class AbstractPollTask(AsynchronousTask):
 		| ---------------------------------------------------
 		| 0      | None
 		"""
-		buf = None
-		if event & self.scheduler.IO_IN:
-			buf = array.array('B')
-			try:
+		buf = array.array('B')
+		try:
 				buf.fromfile(f, self._bufsize)
-			except EOFError:
+		except EOFError:
 				pass
-			except TypeError:
+		except TypeError:
 				# Python 3.2:
 				# TypeError: read() didn't return bytes
 				pass
-			except IOError as e:
+		except IOError as e:
 				# EIO happens with pty on Linux after the
 				# slave end of the pty has been closed.
 				if e.errno == errno.EIO:
@@ -121,23 +119,6 @@ class AbstractPollTask(AsynchronousTask):
 	def _unregister(self):
 		self._registered = False
 
-	def _log_poll_exception(self, event):
-		writemsg_level(
-			"!!! %s received strange poll event: %s\n" % \
-			(self.__class__.__name__, event,),
-			level=logging.ERROR, noiselevel=-1)
-
-	def _unregister_if_appropriate(self, event):
-		if self._registered:
-			if event & self._exceptional_events:
-				self._log_poll_exception(event)
-				self.cancel()
-				self.returncode = self.returncode or os.EX_OK
-				self._async_wait()
-			elif event & self.scheduler.IO_HUP:
-				self.returncode = self.returncode or os.EX_OK
-				self._async_wait()
-
 	def _wait_loop(self, timeout=None):
 		loop = getattr(self.scheduler, '_asyncio_wrapper', self.scheduler)
 		tasks = [self.async_wait()]

diff --git a/pym/_emerge/PipeReader.py b/pym/_emerge/PipeReader.py
index 6b567d8b1..6a3fc9ea6 100644
--- a/pym/_emerge/PipeReader.py
+++ b/pym/_emerge/PipeReader.py
@@ -79,7 +79,7 @@ class PipeReader(AbstractPollTask):
 				break
 
 		while True:
-			data = self._read_array(f, self.scheduler.IO_IN)
+			data = self._read_array(f, None)
 			if data is None:
 				break
 			if data:

diff --git a/pym/_emerge/SubProcess.py b/pym/_emerge/SubProcess.py
index a37482ca4..7d6b03272 100644
--- a/pym/_emerge/SubProcess.py
+++ b/pym/_emerge/SubProcess.py
@@ -12,7 +12,7 @@ import errno
 class SubProcess(AbstractPollTask):
 
 	__slots__ = ("pid",) + \
-		("_dummy_pipe_fd", "_files", "_reg_id", "_waitpid_id")
+		("_dummy_pipe_fd", "_files", "_waitpid_id")
 
 	# This is how much time we allow for waitpid to succeed after
 	# we've sent a kill signal to our subprocess.
@@ -70,10 +70,6 @@ class SubProcess(AbstractPollTask):
 
 		self._registered = False
 
-		if self._reg_id is not None:
-			self.scheduler.source_remove(self._reg_id)
-			self._reg_id = None
-
 		if self._waitpid_id is not None:
 			self.scheduler._asyncio_child_watcher.\
 				remove_child_handler(self._waitpid_id)
@@ -86,19 +82,3 @@ class SubProcess(AbstractPollTask):
 				else:
 					f.close()
 			self._files = None
-
-	def _unregister_if_appropriate(self, event):
-		"""
-		Override the AbstractPollTask._unregister_if_appropriate method to
-		call _async_waitpid instead of wait(), so that event loop recursion
-		is not triggered when the pid exit status is not yet available.
-		"""
-		if self._registered:
-			if event & self._exceptional_events:
-				self._log_poll_exception(event)
-				self._unregister()
-				self.cancel()
-				self._async_waitpid()
-			elif event & self.scheduler.IO_HUP:
-				self._unregister()
-				self._async_waitpid()

diff --git a/pym/portage/util/_async/SchedulerInterface.py b/pym/portage/util/_async/SchedulerInterface.py
index 56b844616..718fbc8e7 100644
--- a/pym/portage/util/_async/SchedulerInterface.py
+++ b/pym/portage/util/_async/SchedulerInterface.py
@@ -11,11 +11,7 @@ from ..SlotObject import SlotObject
 
 class SchedulerInterface(SlotObject):
 
-	_event_loop_attrs = ("IO_ERR", "IO_HUP", "IO_IN",
-		"IO_NVAL", "IO_OUT", "IO_PRI",
-		"io_add_watch",
-		"source_remove",
-
+	_event_loop_attrs = (
 		"add_reader",
 		"add_writer",
 		"call_at",


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2018-04-30  6:29 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-04-29 21:29 [gentoo-commits] proj/portage:master commit in: pym/_emerge/, pym/portage/util/_async/ Zac Medico
  -- strict thread matches above, loose matches on Subject: below --
2018-04-30  6:29 Zac Medico

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox