diff options
author | Zac Medico <zmedico@gentoo.org> | 2012-02-11 21:36:18 -0800 |
---|---|---|
committer | Zac Medico <zmedico@gentoo.org> | 2012-02-11 21:36:18 -0800 |
commit | c36768027d04f10f7af4402f642e93144d1b353b (patch) | |
tree | 40a3452e58af72246e6d8b457e76dd60c27fa224 | |
parent | fc42d39d0ac9043b7a480d914b12fa679e4e2785 (diff) | |
download | portage-c36768027d04f10f7af4402f642e93144d1b353b.tar.gz portage-c36768027d04f10f7af4402f642e93144d1b353b.tar.bz2 portage-c36768027d04f10f7af4402f642e93144d1b353b.zip |
EbuildIpcDaemon: handle POLLHUP, bug #401919
-rw-r--r-- | pym/_emerge/EbuildIpcDaemon.py | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/pym/_emerge/EbuildIpcDaemon.py b/pym/_emerge/EbuildIpcDaemon.py index 5795bfbdc..8414d2020 100644 --- a/pym/_emerge/EbuildIpcDaemon.py +++ b/pym/_emerge/EbuildIpcDaemon.py @@ -5,7 +5,9 @@ import errno import logging import pickle from portage import os +from portage.exception import TryAgain from portage.localization import _ +from portage.locks import lockfile, unlockfile from portage.util import writemsg_level from _emerge.FifoIpcDaemon import FifoIpcDaemon @@ -83,6 +85,28 @@ class EbuildIpcDaemon(FifoIpcDaemon): if reply_hook is not None: reply_hook() + elif event & self.scheduler.IO_HUP: + # This can be triggered due to a race condition which happens when + # the previous _reopen_input() call occurs before the writer has + # closed the pipe (see bug #401919). It's not safe to re-open + # without a lock here, since it's possible that another writer will + # write something to the pipe just before we close it, and in that + # case the write will be lost. Therefore, try for a non-blocking + # lock, and only re-open the pipe if the lock is acquired. + lock_filename = os.path.join( + os.path.dirname(self.input_fifo), '.ipc_lock') + try: + lock_obj = lockfile(lock_filename, unlinkfile=True, + flags=os.O_NONBLOCK) + except TryAgain: + # We'll try again when another IO_HUP event arrives. + pass + else: + try: + self._reopen_input() + finally: + unlockfile(lock_obj) + return True def _send_reply(self, reply): |