From mboxrd@z Thu Jan  1 00:00:00 1970
Received: from pigeon.gentoo.org ([208.92.234.80] helo=lists.gentoo.org)
	by finch.gentoo.org with esmtp (Exim 4.60)
	(envelope-from <gentoo-commits+bounces-326370-garchives=archives.gentoo.org@lists.gentoo.org>)
	id 1Q0KUk-0001NP-Pp
	for garchives@archives.gentoo.org; Thu, 17 Mar 2011 21:12:38 +0000
Received: from pigeon.gentoo.org (localhost [127.0.0.1])
	by pigeon.gentoo.org (Postfix) with SMTP id F24511C01B;
	Thu, 17 Mar 2011 21:12:26 +0000 (UTC)
Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183])
	by pigeon.gentoo.org (Postfix) with ESMTP id ACBF61C01B
	for <gentoo-commits@lists.gentoo.org>; Thu, 17 Mar 2011 21:12:26 +0000 (UTC)
Received: from pelican.gentoo.org (unknown [66.219.59.40])
	(using TLSv1 with cipher ADH-CAMELLIA256-SHA (256/256 bits))
	(No client certificate requested)
	by smtp.gentoo.org (Postfix) with ESMTPS id 0D0AD1B4052
	for <gentoo-commits@lists.gentoo.org>; Thu, 17 Mar 2011 21:12:26 +0000 (UTC)
Received: from localhost.localdomain (localhost [127.0.0.1])
	by pelican.gentoo.org (Postfix) with ESMTP id 7BF098006A
	for <gentoo-commits@lists.gentoo.org>; Thu, 17 Mar 2011 21:12:25 +0000 (UTC)
From: "Zac Medico" <zmedico@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Content-type: text/plain; charset=UTF-8
Reply-To: gentoo-dev@lists.gentoo.org, "Zac Medico" <zmedico@gentoo.org>
Message-ID: <eff879ff0ce7dcc1ce68d5f16de1ec73051f8c18.zmedico@gentoo>
Subject: [gentoo-commits] proj/portage:master commit in: bin/
X-VCS-Repository: proj/portage
X-VCS-Files: bin/ebuild-ipc.py
X-VCS-Directories: bin/
X-VCS-Committer: zmedico
X-VCS-Committer-Name: Zac Medico
X-VCS-Revision: eff879ff0ce7dcc1ce68d5f16de1ec73051f8c18
Date: Thu, 17 Mar 2011 21:12:25 +0000 (UTC)
Precedence: bulk
List-Post: <mailto:gentoo-commits@lists.gentoo.org>
List-Help: <mailto:gentoo-commits+help@lists.gentoo.org>
List-Unsubscribe: <mailto:gentoo-commits+unsubscribe@lists.gentoo.org>
List-Subscribe: <mailto:gentoo-commits+subscribe@lists.gentoo.org>
List-Id: Gentoo Linux mail <gentoo-commits.gentoo.org>
X-BeenThere: gentoo-commits@lists.gentoo.org
Content-Transfer-Encoding: quoted-printable
X-Archives-Salt: 
X-Archives-Hash: 7a040b68a555bf2c551d13219d4aa21d

commit:     eff879ff0ce7dcc1ce68d5f16de1ec73051f8c18
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Thu Mar 17 21:12:13 2011 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Thu Mar 17 21:12:13 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=3Dproj/portage.git;a=
=3Dcommit;h=3Deff879ff

ebuild-ipc: use non-blocking read

This makes it possible for the daemon to send a reply without blocking,
thereby improving performance and also making it possible for the
daemon to do a non-blocking write without a race condition.

This reverts part of commit 81fc303212b8379219cf5d463c8717359b972dba,
which probably didn't help portability anyway. Now, ebuild-ipc is using
non-blocking read with os.read and EAGAIN handling, just like
EbuildIpcDaemon since commit 7e5b81da12dd7bd59f6620840dc0d824e3f4d69a
(known compatible with FreeBSD).

---
 bin/ebuild-ipc.py |   54 ++++++++++++++++++++++++++++++++++++++++-------=
-----
 1 files changed, 41 insertions(+), 13 deletions(-)

diff --git a/bin/ebuild-ipc.py b/bin/ebuild-ipc.py
index d8e7e55..cb77171 100755
--- a/bin/ebuild-ipc.py
+++ b/bin/ebuild-ipc.py
@@ -134,23 +134,43 @@ class EbuildIpc(object):
=20
 		return os.WEXITSTATUS(wait_retval[1])
=20
-	def _receive_reply(self):
+	def _receive_reply(self, input_fd):
=20
-		# File streams are in unbuffered mode since we do atomic
-		# read and write of whole pickles.
-		input_file =3D open(self.ipc_out_fifo, 'rb', 0)
-
-		# For maximum portability, use a single atomic read.
+		# Timeouts are handled by the parent process, so just
+		# block until input is available. For maximum portability,
+		# use a single atomic read.
 		buf =3D None
-		try:
-			buf =3D input_file.read(self._BUFSIZE)
-		except IOError as e:
-			if not buf:
+		while True:
+			try:
+				events =3D select.select([input_fd], [], [])
+			except select.error as e:
 				portage.util.writemsg_level(
-					"ebuild-ipc: %s\n" % (e,),
+					"ebuild-ipc: %s: %s\n" % \
+					(portage.localization._('during select for read'), e),
 					level=3Dlogging.ERROR, noiselevel=3D-1)
+				continue
=20
-		input_file.close()
+			if events[0]:
+				# For maximum portability, use os.read() here since
+				# array.fromfile() and file.read() are both known to
+				# erroneously return an empty string from this
+				# non-blocking fifo stream on FreeBSD (bug #337465).
+				try:
+					buf =3D os.read(input_fd, self._BUFSIZE)
+				except OSError as e:
+					if e.errno !=3D errno.EAGAIN:
+						portage.util.writemsg_level(
+							"ebuild-ipc: %s: %s\n" % \
+							(portage.localization._('read error'), e),
+							level=3Dlogging.ERROR, noiselevel=3D-1)
+						break
+					# Assume that another event will be generated
+					# if there's any relevant data.
+					continue
+
+				# Only one (atomic) read should be necessary.
+				if buf:
+					break
=20
 		retval =3D 2
=20
@@ -192,6 +212,13 @@ class EbuildIpc(object):
 			self._no_daemon_msg()
 			return 2
=20
+		# Open the input fifo before the output fifo, in order to make it
+		# possible for the daemon to send a reply without blocking. This
+		# improves performance, and also makes it possible for the daemon
+		# to do a non-blocking write without a race condition.
+		input_fd =3D os.open(self.ipc_out_fifo,
+			os.O_RDONLY|os.O_NONBLOCK)
+
 		# Use forks so that the child process can handle blocking IO
 		# un-interrupted, while the parent handles all timeout
 		# considerations. This helps to avoid possible race conditions
@@ -231,12 +258,13 @@ class EbuildIpc(object):
=20
 		if pid =3D=3D 0:
 			os.close(pr)
-			retval =3D self._receive_reply()
+			retval =3D self._receive_reply(input_fd)
 			os._exit(retval)
=20
 		os.close(pw)
 		retval =3D self._wait(pid, pr, portage.localization._('during read'))
 		os.close(pr)
+		os.close(input_fd)
 		return retval
=20
 def ebuild_ipc_main(args):