1
2
3
4 import array
5 import errno
6 import logging
7 import os
8
9 from portage.util import writemsg_level
10 from _emerge.AsynchronousTask import AsynchronousTask
13
14 __slots__ = ("scheduler",) + \
15 ("_registered",)
16
17 _bufsize = 4096
18
19 @property
22
23 @property
27
30
32 """
33 NOTE: array.fromfile() is used here only for testing purposes,
34 because it has bugs in all known versions of Python (including
35 Python 2.7 and Python 3.2). See PipeReaderArrayTestCase.
36
37 | POLLIN | RETURN
38 | BIT | VALUE
39 | ---------------------------------------------------
40 | 1 | Read self._bufsize into an instance of
41 | | array.array('B') and return it, handling
42 | | EOFError and IOError. An empty array
43 | | indicates EOF.
44 | ---------------------------------------------------
45 | 0 | None
46 """
47 buf = None
48 if event & self.scheduler.IO_IN:
49 buf = array.array('B')
50 try:
51 buf.fromfile(f, self._bufsize)
52 except EOFError:
53 pass
54 except TypeError:
55
56
57 pass
58 except IOError as e:
59
60
61 if e.errno == errno.EIO:
62
63 pass
64 elif e.errno == errno.EAGAIN:
65
66 buf = None
67 else:
68 raise
69
70 if buf is not None:
71 try:
72
73 buf = buf.tobytes()
74 except AttributeError:
75 buf = buf.tostring()
76
77 return buf
78
80 """
81 | POLLIN | RETURN
82 | BIT | VALUE
83 | ---------------------------------------------------
84 | 1 | Read self._bufsize into a string of bytes,
85 | | handling EAGAIN and EIO. An empty string
86 | | of bytes indicates EOF.
87 | ---------------------------------------------------
88 | 0 | None
89 """
90
91
92
93 buf = None
94 if event & self.scheduler.IO_IN:
95 try:
96 buf = os.read(fd, self._bufsize)
97 except OSError as e:
98
99
100 if e.errno == errno.EIO:
101
102 buf = b''
103 elif e.errno == errno.EAGAIN:
104
105 buf = None
106 else:
107 raise
108
109 return buf
110
112 raise NotImplementedError(self)
113
115 writemsg_level(
116 "!!! %s received strange poll event: %s\n" % \
117 (self.__class__.__name__, event,),
118 level=logging.ERROR, noiselevel=-1)
119
130
136
138
139 if timeout is None:
140 while self._registered:
141 self.scheduler.iteration()
142 return
143
144 def timeout_cb():
145 timeout_cb.timed_out = True
146 return False
147 timeout_cb.timed_out = False
148 timeout_cb.timeout_id = self.scheduler.timeout_add(timeout, timeout_cb)
149
150 try:
151 while self._registered and not timeout_cb.timed_out:
152 self.scheduler.iteration()
153 finally:
154 self.scheduler.source_remove(timeout_cb.timeout_id)
155