Ticket #3114: epoll.diff

File epoll.diff, 5.7 KB (added by therve, 9 years ago)
  • twisted/internet/epollreactor.py

     
    1313Maintainer: U{Jp Calderone <mailto:exarkun@twistedmatrix.com>}
    1414"""
    1515
    16 import sys, errno
     16import sys, errno, select
    1717
    1818from zope.interface import implements
    1919
    2020from twisted.internet.interfaces import IReactorFDSet
    2121
    22 from twisted.python import _epoll
    2322from twisted.python import log
    2423from twisted.internet import posixbase, error
    2524from twisted.internet.main import CONNECTION_LOST
    2625
    2726
    28 _POLL_DISCONNECTED = (_epoll.HUP | _epoll.ERR)
     27try:
     28    select.epoll
     29except AttributeError:
     30    import select26 as select
    2931
     32
     33_POLL_DISCONNECTED = (select.EPOLLHUP | select.EPOLLERR)
     34
     35
     36
    3037class EPollReactor(posixbase.PosixReactorBase):
    3138    """
    3239    A reactor that uses epoll(4).
     
    6168        """
    6269        # Create the poller we're going to use.  The 1024 here is just a hint
    6370        # to the kernel, it is not a hard maximum.
    64         self._poller = _epoll.epoll(1024)
     71        self._poller = select.epoll(1024)
    6572        self._reads = {}
    6673        self._writes = {}
    6774        self._selectables = {}
     
    7784        """
    7885        fd = xer.fileno()
    7986        if fd not in primary:
    80             cmd = _epoll.CTL_ADD
     87            cmd = "register"
    8188            flags = event
    8289            if fd in other:
    8390                flags |= antievent
    84                 cmd = _epoll.CTL_MOD
     91                cmd = "modify"
    8592            primary[fd] = 1
    8693            selectables[fd] = xer
    8794            # epoll_ctl can raise all kinds of IOErrors, and every one
     
    8996            # Let them all through so someone sees a traceback and fixes
    9097            # something.  We'll do the same thing for every other call to
    9198            # this method in this file.
    92             self._poller._control(cmd, fd, flags)
     99            getattr(self._poller, cmd)(fd, flags)
    93100
    94101
    95102    def addReader(self, reader):
    96103        """
    97104        Add a FileDescriptor for notification of data available to read.
    98105        """
    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)
    100108
    101109
    102110    def addWriter(self, writer):
    103111        """
    104112        Add a FileDescriptor for notification of data available to write.
    105113        """
    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)
    107116
    108117
    109118    def _remove(self, xer, primary, other, selectables, event, antievent):
     
    121130            else:
    122131                return
    123132        if fd in primary:
    124             cmd = _epoll.CTL_DEL
    125133            flags = event
    126134            if fd in other:
    127135                flags = antievent
    128                 cmd = _epoll.CTL_MOD
     136                self._poller.modify(fd, flags)
    129137            else:
    130138                del selectables[fd]
     139                self._poller.unregister(fd)
    131140            del primary[fd]
    132141            # See comment above _control call in _add.
    133             self._poller._control(cmd, fd, flags)
    134142
    135143
    136144    def removeReader(self, reader):
    137145        """
    138146        Remove a Selectable for notification of data available to read.
    139147        """
    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)
    141150
    142151
    143152    def removeWriter(self, writer):
    144153        """
    145154        Remove a Selectable for notification of data available to write.
    146155        """
    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)
    148158
    149159    def removeAll(self):
    150160        """
     
    164174            try:
    165175                # Actually, we'll ignore all errors from this, since it's
    166176                # just last-chance cleanup.
    167                 self._poller._control(_epoll.CTL_DEL, fd, 0)
     177                self._poller.unregister(fd, 0)
    168178            except IOError:
    169179                pass
    170180        if self.waker is not None:
     
    188198        """
    189199        if timeout is None:
    190200            timeout = 1
    191         timeout = int(timeout * 1000) # convert seconds to milliseconds
    192201
    193202        try:
    194203            # Limit the number of events to the number of io objects we're
    195204            # currently tracking (because that's maybe a good heuristic) and
    196205            # the amount of time we block to the value specified by our
    197206            # caller.
    198             l = self._poller.wait(len(self._selectables), timeout)
     207            l = self._poller.poll(timeout, max(1, len(self._selectables)))
    199208        except IOError, err:
    200209            if err.errno == errno.EINTR:
    201210                return
     
    223232        """
    224233        why = None
    225234        inRead = False
    226         if event & _POLL_DISCONNECTED and not (event & _epoll.IN):
     235        if event & _POLL_DISCONNECTED and not (event & select.EPOLLIN):
    227236            why = CONNECTION_LOST
    228237        else:
    229238            try:
    230                 if event & _epoll.IN:
     239                if event & select.EPOLLIN:
    231240                    why = selectable.doRead()
    232241                    inRead = True
    233                 if not why and event & _epoll.OUT:
     242                if not why and event & select.EPOLLOUT:
    234243                    why = selectable.doWrite()
    235244                    inRead = False
    236245                if selectable.fileno() != fd: