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 ) 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 ; 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 ; 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 ; Thu, 17 Mar 2011 21:12:25 +0000 (UTC) From: "Zac Medico" To: gentoo-commits@lists.gentoo.org Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Zac Medico" Message-ID: 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: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: quoted-printable X-Archives-Salt: X-Archives-Hash: 7a040b68a555bf2c551d13219d4aa21d commit: eff879ff0ce7dcc1ce68d5f16de1ec73051f8c18 Author: Zac Medico gentoo org> AuthorDate: Thu Mar 17 21:12:13 2011 +0000 Commit: Zac Medico gentoo 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):