Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(588)

Side by Side Diff: third_party/twisted_8_1/twisted/internet/epollreactor.py

Issue 12261012: Remove third_party/twisted_8_1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 # Copyright (c) 2001-2007 Twisted Matrix Laboratories.
2 # See LICENSE for details.
3
4 """
5 An epoll() based implementation of the twisted main loop.
6
7 To install the event loop (and you should do this before any connections,
8 listeners or connectors are added)::
9
10 from twisted.internet import epollreactor
11 epollreactor.install()
12
13 Maintainer: U{Jp Calderone <mailto:exarkun@twistedmatrix.com>}
14 """
15
16 import sys, errno
17
18 from zope.interface import implements
19
20 from twisted.internet.interfaces import IReactorFDSet
21
22 from twisted.python import _epoll
23 from twisted.python import log
24 from twisted.internet import posixbase, error
25 from twisted.internet.main import CONNECTION_LOST
26
27
28 _POLL_DISCONNECTED = (_epoll.HUP | _epoll.ERR)
29
30 class EPollReactor(posixbase.PosixReactorBase):
31 """
32 A reactor that uses epoll(4).
33
34 @ivar _poller: A L{poll} which will be used to check for I/O
35 readiness.
36
37 @ivar _selectables: A dictionary mapping integer file descriptors to
38 instances of L{FileDescriptor} which have been registered with the
39 reactor. All L{FileDescriptors} which are currently receiving read or
40 write readiness notifications will be present as values in this
41 dictionary.
42
43 @ivar _reads: A dictionary mapping integer file descriptors to arbitrary
44 values (this is essentially a set). Keys in this dictionary will be
45 registered with C{_poller} for read readiness notifications which will
46 be dispatched to the corresponding L{FileDescriptor} instances in
47 C{_selectables}.
48
49 @ivar _writes: A dictionary mapping integer file descriptors to arbitrary
50 values (this is essentially a set). Keys in this dictionary will be
51 registered with C{_poller} for write readiness notifications which will
52 be dispatched to the corresponding L{FileDescriptor} instances in
53 C{_selectables}.
54 """
55 implements(IReactorFDSet)
56
57 def __init__(self):
58 """
59 Initialize epoll object, file descriptor tracking dictionaries, and the
60 base class.
61 """
62 # Create the poller we're going to use. The 1024 here is just a hint
63 # to the kernel, it is not a hard maximum.
64 self._poller = _epoll.epoll(1024)
65 self._reads = {}
66 self._writes = {}
67 self._selectables = {}
68 posixbase.PosixReactorBase.__init__(self)
69
70
71 def _add(self, xer, primary, other, selectables, event, antievent):
72 """
73 Private method for adding a descriptor from the event loop.
74
75 It takes care of adding it if new or modifying it if already added
76 for another state (read -> read/write for example).
77 """
78 fd = xer.fileno()
79 if fd not in primary:
80 cmd = _epoll.CTL_ADD
81 flags = event
82 if fd in other:
83 flags |= antievent
84 cmd = _epoll.CTL_MOD
85 primary[fd] = 1
86 selectables[fd] = xer
87 # epoll_ctl can raise all kinds of IOErrors, and every one
88 # indicates a bug either in the reactor or application-code.
89 # Let them all through so someone sees a traceback and fixes
90 # something. We'll do the same thing for every other call to
91 # this method in this file.
92 self._poller._control(cmd, fd, flags)
93
94
95 def addReader(self, reader):
96 """
97 Add a FileDescriptor for notification of data available to read.
98 """
99 self._add(reader, self._reads, self._writes, self._selectables, _epoll.I N, _epoll.OUT)
100
101
102 def addWriter(self, writer):
103 """
104 Add a FileDescriptor for notification of data available to write.
105 """
106 self._add(writer, self._writes, self._reads, self._selectables, _epoll.O UT, _epoll.IN)
107
108
109 def _remove(self, xer, primary, other, selectables, event, antievent):
110 """
111 Private method for removing a descriptor from the event loop.
112
113 It does the inverse job of _add, and also add a check in case of the fd
114 has gone away.
115 """
116 fd = xer.fileno()
117 if fd == -1:
118 for fd, fdes in selectables.items():
119 if xer is fdes:
120 break
121 else:
122 return
123 if fd in primary:
124 cmd = _epoll.CTL_DEL
125 flags = event
126 if fd in other:
127 flags = antievent
128 cmd = _epoll.CTL_MOD
129 else:
130 del selectables[fd]
131 del primary[fd]
132 # See comment above _control call in _add.
133 self._poller._control(cmd, fd, flags)
134
135
136 def removeReader(self, reader):
137 """
138 Remove a Selectable for notification of data available to read.
139 """
140 self._remove(reader, self._reads, self._writes, self._selectables, _epol l.IN, _epoll.OUT)
141
142
143 def removeWriter(self, writer):
144 """
145 Remove a Selectable for notification of data available to write.
146 """
147 self._remove(writer, self._writes, self._reads, self._selectables, _epol l.OUT, _epoll.IN)
148
149 def removeAll(self):
150 """
151 Remove all selectables, and return a list of them.
152 """
153 if self.waker is not None:
154 fd = self.waker.fileno()
155 if fd in self._reads:
156 del self._reads[fd]
157 del self._selectables[fd]
158 result = self._selectables.values()
159 fds = self._selectables.keys()
160 self._reads.clear()
161 self._writes.clear()
162 self._selectables.clear()
163 for fd in fds:
164 try:
165 # Actually, we'll ignore all errors from this, since it's
166 # just last-chance cleanup.
167 self._poller._control(_epoll.CTL_DEL, fd, 0)
168 except IOError:
169 pass
170 if self.waker is not None:
171 fd = self.waker.fileno()
172 self._reads[fd] = 1
173 self._selectables[fd] = self.waker
174 return result
175
176
177 def getReaders(self):
178 return [self._selectables[fd] for fd in self._reads]
179
180
181 def getWriters(self):
182 return [self._selectables[fd] for fd in self._writes]
183
184
185 def doPoll(self, timeout):
186 """
187 Poll the poller for new events.
188 """
189 if timeout is None:
190 timeout = 1
191 timeout = int(timeout * 1000) # convert seconds to milliseconds
192
193 try:
194 # Limit the number of events to the number of io objects we're
195 # currently tracking (because that's maybe a good heuristic) and
196 # the amount of time we block to the value specified by our
197 # caller.
198 l = self._poller.wait(len(self._selectables), timeout)
199 except IOError, err:
200 if err.errno == errno.EINTR:
201 return
202 # See epoll_wait(2) for documentation on the other conditions
203 # under which this can fail. They can only be due to a serious
204 # programming error on our part, so let's just announce them
205 # loudly.
206 raise
207
208 _drdw = self._doReadOrWrite
209 for fd, event in l:
210 try:
211 selectable = self._selectables[fd]
212 except KeyError:
213 pass
214 else:
215 log.callWithLogger(selectable, _drdw, selectable, fd, event)
216
217 doIteration = doPoll
218
219 def _doReadOrWrite(self, selectable, fd, event):
220 """
221 fd is available for read or write, make the work and raise errors
222 if necessary.
223 """
224 why = None
225 inRead = False
226 if event & _POLL_DISCONNECTED and not (event & _epoll.IN):
227 why = CONNECTION_LOST
228 else:
229 try:
230 if event & _epoll.IN:
231 why = selectable.doRead()
232 inRead = True
233 if not why and event & _epoll.OUT:
234 why = selectable.doWrite()
235 inRead = False
236 if selectable.fileno() != fd:
237 why = error.ConnectionFdescWentAway(
238 'Filedescriptor went away')
239 inRead = False
240 except:
241 log.err()
242 why = sys.exc_info()[1]
243 if why:
244 self._disconnectSelectable(selectable, why, inRead)
245
246 def install():
247 """
248 Install the epoll() reactor.
249 """
250 p = EPollReactor()
251 from twisted.internet.main import installReactor
252 installReactor(p)
253
254
255 __all__ = ["EPollReactor", "install"]
256
OLDNEW
« no previous file with comments | « third_party/twisted_8_1/twisted/internet/defer.py ('k') | third_party/twisted_8_1/twisted/internet/error.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698