summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pym/_emerge/EbuildIpcDaemon.py29
1 files changed, 24 insertions, 5 deletions
diff --git a/pym/_emerge/EbuildIpcDaemon.py b/pym/_emerge/EbuildIpcDaemon.py
index efcda9316..5dabe34b3 100644
--- a/pym/_emerge/EbuildIpcDaemon.py
+++ b/pym/_emerge/EbuildIpcDaemon.py
@@ -1,9 +1,12 @@
-# Copyright 2010 Gentoo Foundation
+# Copyright 2010-2011 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
import errno
+import logging
import pickle
from portage import os
+from portage.localization import _
+from portage.util import writemsg_level
from _emerge.FifoIpcDaemon import FifoIpcDaemon
from _emerge.PollConstants import PollConstants
@@ -83,7 +86,23 @@ class EbuildIpcDaemon(FifoIpcDaemon):
def _send_reply(self, reply):
# File streams are in unbuffered mode since we do atomic
- # read and write of whole pickles.
- output_file = open(self.output_fifo, 'wb', 0)
- output_file.write(pickle.dumps(reply))
- output_file.close()
+ # read and write of whole pickles. Use non-blocking mode so
+ # we don't hang if the client is killed before we can send
+ # the reply. We rely on the client opening the other side
+ # of this fifo before it sends its request, since otherwise
+ # we'd have a race condition with this open call raising
+ # ENXIO if the client hasn't opened the fifo yet.
+ try:
+ output_fd = os.open(self.output_fifo,
+ os.O_WRONLY | os.O_NONBLOCK)
+ try:
+ os.write(output_fd, pickle.dumps(reply))
+ finally:
+ os.close(output_fd)
+ except OSError as e:
+ # This probably means that the client has been killed,
+ # which causes open to fail with ENXIO.
+ writemsg_level(
+ "!!! EbuildIpcDaemon %s: %s\n" % \
+ (_('failed to send reply'), e),
+ level=logging.ERROR, noiselevel=-1)