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.
This commit is contained in:
parent
baac01e629
commit
b9052a0f91
|
@ -0,0 +1,2 @@
|
||||||
|
Fixed the layout of the kqueue_event structure on OpenBSD and NetBSD. Fixed
|
||||||
|
the comparison of the kqueue_event objects.
|
|
@ -1779,40 +1779,73 @@ static PyTypeObject kqueue_queue_Type;
|
||||||
#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
|
#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
|
||||||
# define T_UINTPTRT T_ULONGLONG
|
# define T_UINTPTRT T_ULONGLONG
|
||||||
# define T_INTPTRT T_LONGLONG
|
# define T_INTPTRT T_LONGLONG
|
||||||
# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
|
|
||||||
# define UINTPTRT_FMT_UNIT "K"
|
# define UINTPTRT_FMT_UNIT "K"
|
||||||
# define INTPTRT_FMT_UNIT "L"
|
# define INTPTRT_FMT_UNIT "L"
|
||||||
#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
|
#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
|
||||||
# define T_UINTPTRT T_ULONG
|
# define T_UINTPTRT T_ULONG
|
||||||
# define T_INTPTRT T_LONG
|
# define T_INTPTRT T_LONG
|
||||||
# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
|
|
||||||
# define UINTPTRT_FMT_UNIT "k"
|
# define UINTPTRT_FMT_UNIT "k"
|
||||||
# define INTPTRT_FMT_UNIT "l"
|
# define INTPTRT_FMT_UNIT "l"
|
||||||
#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
|
#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
|
||||||
# define T_UINTPTRT T_UINT
|
# define T_UINTPTRT T_UINT
|
||||||
# define T_INTPTRT T_INT
|
# define T_INTPTRT T_INT
|
||||||
# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
|
|
||||||
# define UINTPTRT_FMT_UNIT "I"
|
# define UINTPTRT_FMT_UNIT "I"
|
||||||
# define INTPTRT_FMT_UNIT "i"
|
# define INTPTRT_FMT_UNIT "i"
|
||||||
#else
|
#else
|
||||||
# error uintptr_t does not match int, long, or long long!
|
# error uintptr_t does not match int, long, or long long!
|
||||||
#endif
|
#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.
|
* kevent is not standard and its members vary across BSDs.
|
||||||
*/
|
*/
|
||||||
#if !defined(__OpenBSD__)
|
#ifdef __NetBSD__
|
||||||
# define IDENT_TYPE T_UINTPTRT
|
# define FILTER_TYPE T_UINT32
|
||||||
# define IDENT_CAST intptr_t
|
# define FILTER_FMT_UNIT UINT32_FMT_UNIT
|
||||||
# define DATA_TYPE T_INTPTRT
|
# define FLAGS_TYPE T_UINT32
|
||||||
# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
|
# define FLAGS_FMT_UNIT UINT32_FMT_UNIT
|
||||||
# define IDENT_AsType PyLong_AsUintptr_t
|
# define FFLAGS_TYPE T_UINT32
|
||||||
|
# define FFLAGS_FMT_UNIT UINT32_FMT_UNIT
|
||||||
#else
|
#else
|
||||||
# define IDENT_TYPE T_UINT
|
# define FILTER_TYPE T_SHORT
|
||||||
# define IDENT_CAST int
|
# define FILTER_FMT_UNIT "h"
|
||||||
# define DATA_TYPE T_INT
|
# define FLAGS_TYPE T_USHORT
|
||||||
# define DATA_FMT_UNIT "i"
|
# define FLAGS_FMT_UNIT "H"
|
||||||
# define IDENT_AsType PyLong_AsUnsignedLong
|
# 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
|
#endif
|
||||||
|
|
||||||
/* Unfortunately, we can't store python objects in udata, because
|
/* 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)
|
#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
|
||||||
static struct PyMemberDef kqueue_event_members[] = {
|
static struct PyMemberDef kqueue_event_members[] = {
|
||||||
{"ident", IDENT_TYPE, KQ_OFF(e.ident)},
|
{"ident", T_UINTPTRT, KQ_OFF(e.ident)},
|
||||||
{"filter", T_SHORT, KQ_OFF(e.filter)},
|
{"filter", FILTER_TYPE, KQ_OFF(e.filter)},
|
||||||
{"flags", T_USHORT, KQ_OFF(e.flags)},
|
{"flags", FLAGS_TYPE, KQ_OFF(e.flags)},
|
||||||
{"fflags", T_UINT, KQ_OFF(e.fflags)},
|
{"fflags", T_UINT, KQ_OFF(e.fflags)},
|
||||||
{"data", DATA_TYPE, KQ_OFF(e.data)},
|
{"data", DATA_TYPE, KQ_OFF(e.data)},
|
||||||
{"udata", T_UINTPTRT, KQ_OFF(e.udata)},
|
{"udata", T_UINTPTRT, KQ_OFF(e.udata)},
|
||||||
|
@ -1840,9 +1873,9 @@ kqueue_event_repr(kqueue_event_Object *s)
|
||||||
PyOS_snprintf(
|
PyOS_snprintf(
|
||||||
buf, sizeof(buf),
|
buf, sizeof(buf),
|
||||||
"<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
|
"<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
|
||||||
"data=0x%zd udata=%p>",
|
"data=0x%llx udata=%p>",
|
||||||
(size_t)(s->e.ident), s->e.filter, s->e.flags,
|
(size_t)(s->e.ident), (int)s->e.filter, (unsigned int)s->e.flags,
|
||||||
s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
|
(unsigned int)s->e.fflags, (long long)(s->e.data), (void *)s->e.udata);
|
||||||
return PyUnicode_FromString(buf);
|
return PyUnicode_FromString(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1852,7 +1885,9 @@ kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
|
||||||
PyObject *pfd;
|
PyObject *pfd;
|
||||||
static char *kwlist[] = {"ident", "filter", "flags", "fflags",
|
static char *kwlist[] = {"ident", "filter", "flags", "fflags",
|
||||||
"data", "udata", NULL};
|
"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 */
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PyLong_Check(pfd)
|
if (PyLong_Check(pfd)) {
|
||||||
#if IDENT_TYPE == T_UINT
|
self->e.ident = PyLong_AsSize_t(pfd);
|
||||||
&& PyLong_AsUnsignedLong(pfd) <= UINT_MAX
|
|
||||||
#endif
|
|
||||||
) {
|
|
||||||
self->e.ident = IDENT_AsType(pfd);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
self->e.ident = PyObject_AsFileDescriptor(pfd);
|
self->e.ident = PyObject_AsFileDescriptor(pfd);
|
||||||
|
@ -1882,29 +1913,22 @@ static PyObject *
|
||||||
kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
|
kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
|
||||||
int op)
|
int op)
|
||||||
{
|
{
|
||||||
intptr_t result = 0;
|
int result;
|
||||||
|
|
||||||
if (!kqueue_event_Check(o)) {
|
if (!kqueue_event_Check(o)) {
|
||||||
if (op == Py_EQ || op == Py_NE) {
|
Py_RETURN_NOTIMPLEMENTED;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#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) {
|
switch (op) {
|
||||||
case Py_EQ:
|
case Py_EQ:
|
||||||
result = (result == 0);
|
result = (result == 0);
|
||||||
|
|
Loading…
Reference in New Issue