[Python-checkins] bpo-31893: Fixed select.kqueue(). (#4166)

Serhiy Storchaka webhook-mailer at python.org
Tue Oct 31 07:59:58 EDT 2017


https://github.com/python/cpython/commit/b9052a0f91d2e83bbc27267247a5920c82b242a3
commit: b9052a0f91d2e83bbc27267247a5920c82b242a3
branch: master
author: Serhiy Storchaka <storchaka at gmail.com>
committer: GitHub <noreply at github.com>
date: 2017-10-31T13:59:55+02:00
summary:

bpo-31893: Fixed select.kqueue(). (#4166)

* Fixed the layout of the kqueue_event structure on OpenBSD and NetBSD.
* Fixed the comparison of the kqueue_event objects.

files:
A Misc/NEWS.d/next/Library/2017-10-29-13-51-01.bpo-31893.8LZKEz.rst
M Modules/selectmodule.c

diff --git a/Misc/NEWS.d/next/Library/2017-10-29-13-51-01.bpo-31893.8LZKEz.rst b/Misc/NEWS.d/next/Library/2017-10-29-13-51-01.bpo-31893.8LZKEz.rst
new file mode 100644
index 00000000000..46be7fb3731
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2017-10-29-13-51-01.bpo-31893.8LZKEz.rst
@@ -0,0 +1,2 @@
+Fixed the layout of the kqueue_event structure on OpenBSD and NetBSD. Fixed
+the comparison of the kqueue_event objects.
diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c
index 0f353fbe841..af265d89ff6 100644
--- a/Modules/selectmodule.c
+++ b/Modules/selectmodule.c
@@ -1779,40 +1779,73 @@ static PyTypeObject kqueue_queue_Type;
 #elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
 #   define T_UINTPTRT         T_ULONGLONG
 #   define T_INTPTRT          T_LONGLONG
-#   define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
 #   define UINTPTRT_FMT_UNIT  "K"
 #   define INTPTRT_FMT_UNIT   "L"
 #elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
 #   define T_UINTPTRT         T_ULONG
 #   define T_INTPTRT          T_LONG
-#   define PyLong_AsUintptr_t PyLong_AsUnsignedLong
 #   define UINTPTRT_FMT_UNIT  "k"
 #   define INTPTRT_FMT_UNIT   "l"
 #elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
 #   define T_UINTPTRT         T_UINT
 #   define T_INTPTRT          T_INT
-#   define PyLong_AsUintptr_t PyLong_AsUnsignedLong
 #   define UINTPTRT_FMT_UNIT  "I"
 #   define INTPTRT_FMT_UNIT   "i"
 #else
 #   error uintptr_t does not match int, long, or long long!
 #endif
 
+#if SIZEOF_LONG_LONG == 8
+#   define T_INT64          T_LONGLONG
+#   define INT64_FMT_UNIT   "L"
+#elif SIZEOF_LONG == 8
+#   define T_INT64          T_LONG
+#   define INT64_FMT_UNIT   "l"
+#elif SIZEOF_INT == 8
+#   define T_INT64          T_INT
+#   define INT64_FMT_UNIT   "i"
+#else
+#   define INT64_FMT_UNIT   "_"
+#endif
+
+#if SIZEOF_LONG_LONG == 4
+#   define T_UINT32         T_ULONGLONG
+#   define UINT32_FMT_UNIT  "K"
+#elif SIZEOF_LONG == 4
+#   define T_UINT32         T_ULONG
+#   define UINT32_FMT_UNIT  "k"
+#elif SIZEOF_INT == 4
+#   define T_UINT32         T_UINT
+#   define UINT32_FMT_UNIT  "I"
+#else
+#   define UINT32_FMT_UNIT  "_"
+#endif
+
 /*
  * kevent is not standard and its members vary across BSDs.
  */
-#if !defined(__OpenBSD__)
-#   define IDENT_TYPE  T_UINTPTRT
-#   define IDENT_CAST  intptr_t
-#   define DATA_TYPE   T_INTPTRT
-#   define DATA_FMT_UNIT INTPTRT_FMT_UNIT
-#   define IDENT_AsType PyLong_AsUintptr_t
+#ifdef __NetBSD__
+#   define FILTER_TYPE      T_UINT32
+#   define FILTER_FMT_UNIT  UINT32_FMT_UNIT
+#   define FLAGS_TYPE       T_UINT32
+#   define FLAGS_FMT_UNIT   UINT32_FMT_UNIT
+#   define FFLAGS_TYPE      T_UINT32
+#   define FFLAGS_FMT_UNIT  UINT32_FMT_UNIT
 #else
-#   define IDENT_TYPE  T_UINT
-#   define IDENT_CAST  int
-#   define DATA_TYPE   T_INT
-#   define DATA_FMT_UNIT "i"
-#   define IDENT_AsType PyLong_AsUnsignedLong
+#   define FILTER_TYPE      T_SHORT
+#   define FILTER_FMT_UNIT  "h"
+#   define FLAGS_TYPE       T_USHORT
+#   define FLAGS_FMT_UNIT   "H"
+#   define FFLAGS_TYPE      T_UINT
+#   define FFLAGS_FMT_UNIT  "I"
+#endif
+
+#ifdef __FreeBSD__
+#   define DATA_TYPE        T_INTPTRT
+#   define DATA_FMT_UNIT    INTPTR_FMT_UNIT
+#else
+#   define DATA_TYPE        T_INT64
+#   define DATA_FMT_UNIT    INT64_FMT_UNIT
 #endif
 
 /* Unfortunately, we can't store python objects in udata, because
@@ -1822,9 +1855,9 @@ static PyTypeObject kqueue_queue_Type;
 
 #define KQ_OFF(x) offsetof(kqueue_event_Object, x)
 static struct PyMemberDef kqueue_event_members[] = {
-    {"ident",           IDENT_TYPE,     KQ_OFF(e.ident)},
-    {"filter",          T_SHORT,        KQ_OFF(e.filter)},
-    {"flags",           T_USHORT,       KQ_OFF(e.flags)},
+    {"ident",           T_UINTPTRT,     KQ_OFF(e.ident)},
+    {"filter",          FILTER_TYPE,    KQ_OFF(e.filter)},
+    {"flags",           FLAGS_TYPE,     KQ_OFF(e.flags)},
     {"fflags",          T_UINT,         KQ_OFF(e.fflags)},
     {"data",            DATA_TYPE,      KQ_OFF(e.data)},
     {"udata",           T_UINTPTRT,     KQ_OFF(e.udata)},
@@ -1840,9 +1873,9 @@ kqueue_event_repr(kqueue_event_Object *s)
     PyOS_snprintf(
         buf, sizeof(buf),
         "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
-        "data=0x%zd udata=%p>",
-        (size_t)(s->e.ident), s->e.filter, s->e.flags,
-        s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
+        "data=0x%llx udata=%p>",
+        (size_t)(s->e.ident), (int)s->e.filter, (unsigned int)s->e.flags,
+        (unsigned int)s->e.fflags, (long long)(s->e.data), (void *)s->e.udata);
     return PyUnicode_FromString(buf);
 }
 
@@ -1852,7 +1885,9 @@ kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
     PyObject *pfd;
     static char *kwlist[] = {"ident", "filter", "flags", "fflags",
                              "data", "udata", NULL};
-    static const char fmt[] = "O|hHI" DATA_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
+    static const char fmt[] = "O|"
+                FILTER_FMT_UNIT FLAGS_FMT_UNIT FFLAGS_FMT_UNIT DATA_FMT_UNIT
+                UINTPTRT_FMT_UNIT ":kevent";
 
     EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
 
@@ -1862,12 +1897,8 @@ kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
         return -1;
     }
 
-    if (PyLong_Check(pfd)
-#if IDENT_TYPE == T_UINT
-        && PyLong_AsUnsignedLong(pfd) <= UINT_MAX
-#endif
-    ) {
-        self->e.ident = IDENT_AsType(pfd);
+    if (PyLong_Check(pfd)) {
+        self->e.ident = PyLong_AsSize_t(pfd);
     }
     else {
         self->e.ident = PyObject_AsFileDescriptor(pfd);
@@ -1882,28 +1913,21 @@ static PyObject *
 kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
                          int op)
 {
-    intptr_t result = 0;
+    int result;
 
     if (!kqueue_event_Check(o)) {
-        if (op == Py_EQ || op == Py_NE) {
-            PyObject *res = op == Py_EQ ? Py_False : Py_True;
-            Py_INCREF(res);
-            return res;
-        }
-        PyErr_Format(PyExc_TypeError,
-            "can't compare %.200s to %.200s",
-            Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
-        return NULL;
-    }
-    if (((result = (IDENT_CAST)(s->e.ident - o->e.ident)) == 0) &&
-        ((result = s->e.filter - o->e.filter) == 0) &&
-        ((result = s->e.flags - o->e.flags) == 0) &&
-        ((result = (int)(s->e.fflags - o->e.fflags)) == 0) &&
-        ((result = s->e.data - o->e.data) == 0) &&
-        ((result = s->e.udata - o->e.udata) == 0)
-       ) {
-        result = 0;
-    }
+        Py_RETURN_NOTIMPLEMENTED;
+    }
+
+#define CMP(a, b) ((a) != (b)) ? ((a) < (b) ? -1 : 1)
+    result = CMP(s->e.ident, o->e.ident)
+           : CMP(s->e.filter, o->e.filter)
+           : CMP(s->e.flags, o->e.flags)
+           : CMP(s->e.fflags, o->e.fflags)
+           : CMP(s->e.data, o->e.data)
+           : CMP((intptr_t)s->e.udata, (intptr_t)o->e.udata)
+           : 0;
+#undef CMP
 
     switch (op) {
     case Py_EQ:



More information about the Python-checkins mailing list