Gentoo Archives: gentoo-portage-dev

From: Zac Medico <zmedico@g.o>
To: gentoo-portage-dev@l.g.o
Cc: Zac Medico <zmedico@g.o>
Subject: [gentoo-portage-dev] [PATCH] AbstractPollTask._read_buf: read regardless of event flags (531724)
Date: Fri, 26 Dec 2014 09:01:02
Message-Id: 1419584441-23770-1-git-send-email-zmedico@gentoo.org
1 PipeReaderPtyTestCase shows that data may be lost unless we attempt to
2 read data for every poll event, regardless of the event flags.
3
4 Therefore, always read, regardless of the event flags. This is safe to
5 do because all consumers of this API use non-blocking mode and properly
6 handle EAGAIN (signaled when this method returns None).
7
8 X-Gentoo-Bug: 531724
9 X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=531724
10 ---
11 pym/_emerge/AbstractPollTask.py | 50 +++++++++++++++++++++++------------------
12 1 file changed, 28 insertions(+), 22 deletions(-)
13
14 diff --git a/pym/_emerge/AbstractPollTask.py b/pym/_emerge/AbstractPollTask.py
15 index 3f6dd6c..48e7590 100644
16 --- a/pym/_emerge/AbstractPollTask.py
17 +++ b/pym/_emerge/AbstractPollTask.py
18 @@ -78,33 +78,39 @@ class AbstractPollTask(AsynchronousTask):
19
20 def _read_buf(self, fd, event):
21 """
22 - | POLLIN | RETURN
23 - | BIT | VALUE
24 - | ---------------------------------------------------
25 - | 1 | Read self._bufsize into a string of bytes,
26 - | | handling EAGAIN and EIO. An empty string
27 - | | of bytes indicates EOF.
28 - | ---------------------------------------------------
29 - | 0 | None
30 + Read self._bufsize into a string of bytes, handling EAGAIN and
31 + EIO. This will only call os.read() once, so the caller should
32 + call this method in a loop until either None or an empty string
33 + of bytes is returned. An empty string of bytes indicates EOF.
34 + None indicates EAGAIN.
35 +
36 + NOTE: os.read() will be called regardless of the event flags,
37 + since otherwise data may be lost (see bug #531724).
38 +
39 + @param fd: file descriptor (non-blocking mode required)
40 + @type fd: int
41 + @param event: poll event flags
42 + @type event: int
43 + @rtype: bytes or None
44 + @return: A string of bytes, or None
45 """
46 # NOTE: array.fromfile() is no longer used here because it has
47 # bugs in all known versions of Python (including Python 2.7
48 # and Python 3.2).
49 buf = None
50 - if event & self.scheduler.IO_IN:
51 - try:
52 - buf = os.read(fd, self._bufsize)
53 - except OSError as e:
54 - # EIO happens with pty on Linux after the
55 - # slave end of the pty has been closed.
56 - if e.errno == errno.EIO:
57 - # EOF: return empty string of bytes
58 - buf = b''
59 - elif e.errno == errno.EAGAIN:
60 - # EAGAIN: return None
61 - buf = None
62 - else:
63 - raise
64 + try:
65 + buf = os.read(fd, self._bufsize)
66 + except OSError as e:
67 + # EIO happens with pty on Linux after the
68 + # slave end of the pty has been closed.
69 + if e.errno == errno.EIO:
70 + # EOF: return empty string of bytes
71 + buf = b''
72 + elif e.errno == errno.EAGAIN:
73 + # EAGAIN: return None
74 + buf = None
75 + else:
76 + raise
77
78 return buf
79
80 --
81 2.0.5

Replies