Ticket #1918: issue_1918.patch

File issue_1918.patch, 6.6 KB (added by psykidellic, 5 years ago)

kqueue using the Python select module.

  • twisted/internet/kqreactor.py

     
    1010    | from twisted.internet import kqreactor 
    1111    | kqreactor.install() 
    1212 
    13 This reactor only works on FreeBSD and requires PyKQueue 1.3, which is 
    14 available at:  U{http://people.freebsd.org/~dwhite/PyKQueue/} 
     13This reactor only works on FreeBSD and requires Python 2.6 and above select.kqueue 
     14module or the backport of it for Python 2.5 U{http://pypi.python.org/pypi/select26/0.1a3} 
    1515 
     16You're going to need to patch select26:: 
    1617 
     18# HG changeset patch -- Bitbucket.org 
     19# Project select26 
     20# URL http://bitbucket.org/psykidellic/select26/overview/ 
     21# User psykidellic 
     22# Date 1268883306 25200 
     23# Node ID aefd0e6a228b32cb4673e32806fcb415ff79152f 
     24# Parent  d79af7cb2ea63803bcd621a11aaa3739f882d135 
     25Apply the patch 
    1726 
    18 You're going to need to patch PyKqueue:: 
     27--- a/select26module.c 
     28+++ b/select26module.c 
     29@@ -861,7 +861,7 @@ kqueue_queue_control(kqueue_queue_Object 
     30        if (nevents < 0) { 
     31                PyErr_Format(PyExc_ValueError, 
     32                        "Length of eventlist must be 0 or positive, got %d", 
     33-                       nchanges); 
     34+                       nevents); 
     35                return NULL; 
     36        } 
     37  
     38@@ -927,7 +927,7 @@ kqueue_queue_control(kqueue_queue_Object 
     39                                        "select26.kevent objects"); 
     40                                goto error; 
     41                        } else { 
     42-                               chl[i] = ((kqueue_event_Object *)ei)->e; 
     43+                               chl[i++] = ((kqueue_event_Object *)ei)->e; 
     44                        } 
     45                        Py_DECREF(ei); 
     46                } 
    1947 
    20     ===================================================== 
    21     --- PyKQueue-1.3/kqsyscallmodule.c  Sun Jan 28 21:59:50 2001 
    22     +++ PyKQueue-1.3/kqsyscallmodule.c.new      Tue Jul 30 18:06:08 2002 
    23     @@ -137,7 +137,7 @@ 
    24      } 
    25       
    26      statichere PyTypeObject KQEvent_Type = { 
    27     -  PyObject_HEAD_INIT(NULL) 
    28     +  PyObject_HEAD_INIT(&PyType_Type) 
    29        0,                             // ob_size 
    30        "KQEvent",                     // tp_name 
    31        sizeof(KQEventObject),         // tp_basicsize 
    32     @@ -291,13 +291,14 @@ 
    33       
    34        /* Build timespec for timeout */ 
    35        totimespec.tv_sec = timeout / 1000; 
    36     -  totimespec.tv_nsec = (timeout % 1000) * 100000; 
    37     +  totimespec.tv_nsec = (timeout % 1000) * 1000000; 
    38       
    39        // printf("timespec: sec=%d nsec=%d\\n", totimespec.tv_sec, totimespec.tv_nsec); 
    40       
    41        /* Make the call */ 
    42     - 
    43     +  Py_BEGIN_ALLOW_THREADS 
    44        gotNumEvents = kevent (self->fd, changelist, haveNumEvents, triggered, wantNumEvents, &totimespec); 
    45     +  Py_END_ALLOW_THREADS 
    46       
    47        /* Don't need the input event list anymore, so get rid of it */ 
    48        free (changelist); 
    49     @@ -361,7 +362,7 @@ 
    50      statichere PyTypeObject KQueue_Type = { 
    51             /* The ob_type field must be initialized in the module init function 
    52              * to be portable to Windows without using C++. */ 
    53     -   PyObject_HEAD_INIT(NULL) 
    54     +   PyObject_HEAD_INIT(&PyType_Type) 
    55             0,                  /*ob_size*/ 
    56             "KQueue",                   /*tp_name*/ 
    57             sizeof(KQueueObject),       /*tp_basicsize*/ 
     48A complete repo with the change is available at: 
     49U{http://bitbucket.org/psykidellic/select26/} 
    5850 
    5951""" 
    6052 
     
    6254 
    6355from zope.interface import implements 
    6456 
    65 from kqsyscall import EVFILT_READ, EVFILT_WRITE, EV_DELETE, EV_ADD 
    66 from kqsyscall import kqueue, kevent 
    67  
     57try: 
     58    import select26 as select 
     59except ImportError: 
     60    import select 
     61     
    6862from twisted.internet.interfaces import IReactorFDSet 
    6963 
    7064from twisted.python import log, failure 
     
    10296        Initialize kqueue object, file descriptor tracking dictionaries, and the 
    10397        base class. 
    10498        """ 
    105         self._kq = kqueue() 
     99        self._kq = select.kqueue() 
    106100        self._reads = {} 
    107101        self._writes = {} 
    108102        self._selectables = {} 
     
    110104 
    111105 
    112106    def _updateRegistration(self, *args): 
    113         self._kq.kevent([kevent(*args)], 0, 0) 
     107        self._kq.control([select.kevent(*args)], 0, 0) 
    114108 
    115109    def addReader(self, reader): 
    116110        """Add a FileDescriptor for notification of data available to read. 
     
    119113        if fd not in self._reads: 
    120114            self._selectables[fd] = reader 
    121115            self._reads[fd] = 1 
    122             self._updateRegistration(fd, EVFILT_READ, EV_ADD) 
     116            self._updateRegistration(fd, select.KQ_FILTER_READ, select.KQ_EV_ADD) 
    123117 
    124118    def addWriter(self, writer): 
    125119        """Add a FileDescriptor for notification of data available to write. 
     
    128122        if fd not in self._writes: 
    129123            self._selectables[fd] = writer 
    130124            self._writes[fd] = 1 
    131             self._updateRegistration(fd, EVFILT_WRITE, EV_ADD) 
     125            self._updateRegistration(fd, select.KQ_FILTER_WRITE, select.KQ_EV_ADD) 
    132126 
    133127    def removeReader(self, reader): 
    134128        """Remove a Selectable for notification of data available to read. 
     
    138132            del self._reads[fd] 
    139133            if fd not in self._writes: 
    140134                del self._selectables[fd] 
    141             self._updateRegistration(fd, EVFILT_READ, EV_DELETE) 
     135            self._updateRegistration(fd, select.KQ_FILTER_READ, select.KQ_EV_DELETE) 
    142136 
    143137    def removeWriter(self, writer): 
    144138        """Remove a Selectable for notification of data available to write. 
     
    148142            del self._writes[fd] 
    149143            if fd not in self._reads: 
    150144                del self._selectables[fd] 
    151             self._updateRegistration(fd, EVFILT_WRITE, EV_DELETE) 
     145            self._updateRegistration(fd, select.KQ_FILTER_WRITE, select.KQ_EV_DELETE) 
    152146 
    153147    def removeAll(self): 
    154148        """ 
     
    169163 
    170164    def doKEvent(self, timeout): 
    171165        """Poll the kqueue for new events.""" 
    172         if timeout is None: 
    173             timeout = 1000 
    174         else: 
    175             timeout = int(timeout * 1000) # convert seconds to milliseconds 
     166        #if timeout is None: 
     167        #    timeout = 1000 
     168        #else: 
     169        #    timeout = int(timeout * 1000) # convert seconds to milliseconds 
    176170 
    177171        try: 
    178             l = self._kq.kevent([], len(self._selectables), timeout) 
     172            l = self._kq.control([], len(self._selectables), timeout) 
    179173        except OSError, e: 
    180174            if e[0] == errno.EINTR: 
    181175                return 
     
    195189 
    196190    def _doWriteOrRead(self, selectable, fd, filter): 
    197191        try: 
    198             if filter == EVFILT_READ: 
     192            if filter == select.KQ_FILTER_READ: 
    199193                why = selectable.doRead() 
    200             if filter == EVFILT_WRITE: 
     194            if filter == select.KQ_FILTER_WRITE: 
    201195                why = selectable.doWrite() 
    202196            if not selectable.fileno() == fd: 
    203197                why = main.CONNECTION_LOST