Ticket #3114: epoll.diff
| File epoll.diff, 5.7 KB (added by therve, 5 years ago) |
|---|
-
twisted/internet/epollreactor.py
13 13 Maintainer: U{Jp Calderone <mailto:exarkun@twistedmatrix.com>} 14 14 """ 15 15 16 import sys, errno 16 import sys, errno, select 17 17 18 18 from zope.interface import implements 19 19 20 20 from twisted.internet.interfaces import IReactorFDSet 21 21 22 from twisted.python import _epoll23 22 from twisted.python import log 24 23 from twisted.internet import posixbase, error 25 24 from twisted.internet.main import CONNECTION_LOST 26 25 27 26 28 _POLL_DISCONNECTED = (_epoll.HUP | _epoll.ERR) 27 try: 28 select.epoll 29 except AttributeError: 30 import select26 as select 29 31 32 33 _POLL_DISCONNECTED = (select.EPOLLHUP | select.EPOLLERR) 34 35 36 30 37 class EPollReactor(posixbase.PosixReactorBase): 31 38 """ 32 39 A reactor that uses epoll(4). … … 61 68 """ 62 69 # Create the poller we're going to use. The 1024 here is just a hint 63 70 # to the kernel, it is not a hard maximum. 64 self._poller = _epoll.epoll(1024)71 self._poller = select.epoll(1024) 65 72 self._reads = {} 66 73 self._writes = {} 67 74 self._selectables = {} … … 77 84 """ 78 85 fd = xer.fileno() 79 86 if fd not in primary: 80 cmd = _epoll.CTL_ADD87 cmd = "register" 81 88 flags = event 82 89 if fd in other: 83 90 flags |= antievent 84 cmd = _epoll.CTL_MOD91 cmd = "modify" 85 92 primary[fd] = 1 86 93 selectables[fd] = xer 87 94 # epoll_ctl can raise all kinds of IOErrors, and every one … … 89 96 # Let them all through so someone sees a traceback and fixes 90 97 # something. We'll do the same thing for every other call to 91 98 # this method in this file. 92 self._poller._control(cmd,fd, flags)99 getattr(self._poller, cmd)(fd, flags) 93 100 94 101 95 102 def addReader(self, reader): 96 103 """ 97 104 Add a FileDescriptor for notification of data available to read. 98 105 """ 99 self._add(reader, self._reads, self._writes, self._selectables, _epoll.IN, _epoll.OUT) 106 self._add(reader, self._reads, self._writes, self._selectables, 107 select.EPOLLIN, select.EPOLLOUT) 100 108 101 109 102 110 def addWriter(self, writer): 103 111 """ 104 112 Add a FileDescriptor for notification of data available to write. 105 113 """ 106 self._add(writer, self._writes, self._reads, self._selectables, _epoll.OUT, _epoll.IN) 114 self._add(writer, self._writes, self._reads, self._selectables, 115 select.EPOLLOUT, select.EPOLLIN) 107 116 108 117 109 118 def _remove(self, xer, primary, other, selectables, event, antievent): … … 121 130 else: 122 131 return 123 132 if fd in primary: 124 cmd = _epoll.CTL_DEL125 133 flags = event 126 134 if fd in other: 127 135 flags = antievent 128 cmd = _epoll.CTL_MOD136 self._poller.modify(fd, flags) 129 137 else: 130 138 del selectables[fd] 139 self._poller.unregister(fd) 131 140 del primary[fd] 132 141 # See comment above _control call in _add. 133 self._poller._control(cmd, fd, flags)134 142 135 143 136 144 def removeReader(self, reader): 137 145 """ 138 146 Remove a Selectable for notification of data available to read. 139 147 """ 140 self._remove(reader, self._reads, self._writes, self._selectables, _epoll.IN, _epoll.OUT) 148 self._remove(reader, self._reads, self._writes, self._selectables, 149 select.EPOLLIN, select.EPOLLOUT) 141 150 142 151 143 152 def removeWriter(self, writer): 144 153 """ 145 154 Remove a Selectable for notification of data available to write. 146 155 """ 147 self._remove(writer, self._writes, self._reads, self._selectables, _epoll.OUT, _epoll.IN) 156 self._remove(writer, self._writes, self._reads, self._selectables, 157 select.EPOLLOUT, select.EPOLLIN) 148 158 149 159 def removeAll(self): 150 160 """ … … 164 174 try: 165 175 # Actually, we'll ignore all errors from this, since it's 166 176 # just last-chance cleanup. 167 self._poller. _control(_epoll.CTL_DEL,fd, 0)177 self._poller.unregister(fd, 0) 168 178 except IOError: 169 179 pass 170 180 if self.waker is not None: … … 188 198 """ 189 199 if timeout is None: 190 200 timeout = 1 191 timeout = int(timeout * 1000) # convert seconds to milliseconds192 201 193 202 try: 194 203 # Limit the number of events to the number of io objects we're 195 204 # currently tracking (because that's maybe a good heuristic) and 196 205 # the amount of time we block to the value specified by our 197 206 # caller. 198 l = self._poller. wait(len(self._selectables), timeout)207 l = self._poller.poll(timeout, max(1, len(self._selectables))) 199 208 except IOError, err: 200 209 if err.errno == errno.EINTR: 201 210 return … … 223 232 """ 224 233 why = None 225 234 inRead = False 226 if event & _POLL_DISCONNECTED and not (event & _epoll.IN):235 if event & _POLL_DISCONNECTED and not (event & select.EPOLLIN): 227 236 why = CONNECTION_LOST 228 237 else: 229 238 try: 230 if event & _epoll.IN:239 if event & select.EPOLLIN: 231 240 why = selectable.doRead() 232 241 inRead = True 233 if not why and event & _epoll.OUT:242 if not why and event & select.EPOLLOUT: 234 243 why = selectable.doWrite() 235 244 inRead = False 236 245 if selectable.fileno() != fd:
