8000 bpo-31893: Fixed select.kqueue(). (GH-4166) (#4190) · python/cpython@f9a639b · GitHub
[go: up one dir, main page]

Skip to content

Commit f9a639b

Browse files
miss-islingtonserhiy-storchaka
authored andcommitted
bpo-31893: Fixed select.kqueue(). (GH-4166) (#4190)
* Fixed the layout of the kqueue_event structure on OpenBSD and NetBSD. * Fixed the comparison of the kqueue_event objects. (cherry picked from commit b9052a0)
1 parent 5db3208 commit f9a639b

File tree

2 files changed

+73
-47
lines changed

2 files changed

+73
-47
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fixed the layout of the kqueue_event structure on OpenBSD and NetBSD. Fixed
2+
the comparison of the kqueue_event objects.

Modules/selectmodule.c

Lines changed: 71 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1780,40 +1780,73 @@ static PyTypeObject kqueue_queue_Type;
17801780
#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
17811781
# define T_UINTPTRT T_ULONGLONG
17821782
# define T_INTPTRT T_LONGLONG
1783-
# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
17841783
# define UINTPTRT_FMT_UNIT "K"
17851784
# define INTPTRT_FMT_UNIT "L"
17861785
#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
17871786
# define T_UINTPTRT T_ULONG
17881787
# define T_INTPTRT T_LONG
1789-
# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
17901788
# define UINTPTRT_FMT_UNIT "k"
17911789
# define INTPTRT_FMT_UNIT "l"
17921790
#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
17931791
# define T_UINTPTRT T_UINT
17941792
# define T_INTPTRT T_INT
1795-
# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
17961793
# define UINTPTRT_FMT_UNIT "I"
17971794
# define INTPTRT_FMT_UNIT "i"
17981795
#else
17991796
# error uintptr_t does not match int, long, or long long!
18001797
#endif
18011798

1799+
#if SIZEOF_LONG_LONG == 8
1800+
# define T_INT64 T_LONGLONG
1801+
# define INT64_FMT_UNIT "L"
1802+
#elif SIZEOF_LONG == 8
1803+
# define T_INT64 T_LONG
1804+
# define INT64_FMT_UNIT "l"
1805+
#elif SIZEOF_INT == 8
1806+
# define T_INT64 T_INT
1807+
# define INT64_FMT_UNIT "i"
1808+
#else
1809+
# define INT64_FMT_UNIT "_"
1810+
#endif
1811+
1812+
#if SIZEOF_LONG_LONG == 4
1813+
# define T_UINT32 T_ULONGLONG
1814+
# define UINT32_FMT_UNIT "K"
1815+
#elif SIZEOF_LONG == 4
1816+
# define T_UINT32 T_ULONG
1817+
# define UINT32_FMT_UNIT "k"
1818+
#elif SIZEOF_INT == 4
1819+
# define T_UINT32 T_UINT
1820+
# define UINT32_FMT_UNIT "I"
1821+
#else
1822+
# define UINT32_FMT_UNIT "_"
1823+
#endif
1824+
18021825
/*
18031826
* kevent is not standard and its members vary across BSDs.
18041827
*/
1805-
#if !defined(__OpenBSD__)
1806-
# define IDENT_TYPE T_UINTPTRT
1807-
# define IDENT_CAST intptr_t
1808-
# define DATA_TYPE T_INTPTRT
1809-
# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
1810-
# define IDENT_AsType PyLong_AsUintptr_t
1828+
#ifdef __NetBSD__
1829+
# define FILTER_TYPE T_UINT32
1830+
# define FILTER_FMT_UNIT UINT32_FMT_UNIT
1831+
# define FLAGS_TYPE T_UINT32
1832+
# define FLAGS_FMT_UNIT UINT32_FMT_UNIT
1833+
# define FFLAGS_TYPE T_UINT32
1834+
# define FFLAGS_FMT_UNIT UINT32_FMT_UNIT
18111835
#else
1812-
# define IDENT_TYPE T_UINT
1813-
# define IDENT_CAST int
1814-
# define DATA_TYPE T_INT
1815-
# define DATA_FMT_UNIT "i"
1816-
# define IDENT_AsType PyLong_AsUnsignedLong
1836+
# define FILTER_TYPE T_SHORT
1837+
# define FILTER_FMT_UNIT "h"
1838+
# define FLAGS_TYPE T_USHORT
1839+
# define FLAGS_FMT_UNIT "H"
1840+
# define FFLAGS_TYPE T_UINT
1841+
# define FFLAGS_FMT_UNIT "I"
1842+
#endif
1843+
1844+
#ifdef __FreeBSD__
1845+
# define DATA_TYPE T_INTPTRT
1846+
# define DATA_FMT_UNIT INTPTR_FMT_UNIT
1847+
#else
1848+
# define DATA_TYPE T_INT64
1849+
# define DATA_FMT_UNIT INT64_FMT_UNIT
18171850
#endif
18181851

18191852
/* Unfortunately, we can't store python objects in udata, because
@@ -1823,9 +1856,9 @@ static PyTypeObject kqueue_queue_Type;
18231856

18241857
#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
18251858
static struct PyMemberDef kqueue_event_members[] = {
1826-
{"ident", IDENT_TYPE, KQ_OFF(e.ident)},
1827-
{"filter", T_SHORT, KQ_OFF(e.filter)},
1828-
{"flags", T_USHORT, KQ_OFF(e.flags)},
1859+
{"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1860+
{"filter", FILTER_TYPE, KQ_OFF(e.filter)},
1861+
{"flags", FLAGS_TYPE, KQ_OFF(e.flags)},
18291862
{"fflags", T_UINT, KQ_OFF(e.fflags)},
18301863
{"data", DATA_TYPE, KQ_OFF(e.data)},
18311864
{"udata", T_UINTPTRT, KQ_OFF(e.udata)},
@@ -1841,9 +1874,9 @@ kqueue_event_repr(kqueue_event_Object *s)
18411874
PyOS_snprintf(
18421875
buf, sizeof(buf),
18431876
"<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1844-
"data=0x%zd udata=%p>",
1845-
(size_t)(s->e.ident), s->e.filter, s->e.flags,
1846-
s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1877+
"data=0x%llx udata=%p>",
1878+
(size_t)(s->e.ident), (int)s->e.filter, (unsigned int)s->e.flags,
1879+
(unsigned int)s->e.fflags, (long long)(s->e.data), (void *)s->e.udata);
18471880
return PyUnicode_FromString(buf);
18481881
}
18491882

@@ -1853,7 +1886,9 @@ kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
18531886
PyObject *pfd;
18541887
static char *kwlist[] = {"ident", "filter", "flags", "fflags",
18551888
"data", "udata", NULL};
1856-
static const char fmt[] = "O|hHI" DATA_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
1889+
static const char fmt[] = "O|"
1890+
FILTER_FMT_UNIT FLAGS_FMT_UNIT FFLAGS_FMT_UNIT DATA_FMT_UNIT
1891+
UINTPTRT_FMT_UNIT ":kevent";
18571892

18581893
EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
18591894

@@ -1863,12 +1898,8 @@ kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
18631898
return -1;
18641899
}
18651900

1866-
if (PyLong_Check(pfd)
1867-
#if IDENT_TYPE == T_UINT
1868-
&& PyLong_AsUnsignedLong(pfd) <= UINT_MAX
1869-
#endif
1870-
) {
1871-
self->e.ident = IDENT_AsType(pfd);
1901+
if (PyLong_Check(pfd)) {
1902+
self->e.ident = PyLong_AsSize_t(pfd);
18721903
}
18731904
else {
18741905
self->e.ident = PyObject_AsFileDescriptor(pfd);
@@ -1883,28 +1914,21 @@ static PyObject *
18831914
kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
18841915
int op)
18851916
{
1886-
intptr_t result = 0;
1917+
int result;
18871918

18881919
if (!kqueue_event_Check(o)) {
1889-
if (op == Py_EQ || op == Py_NE) {
1890-
PyObject *res = op == Py_EQ ? Py_False : Py_True;
1891-
Py_INCREF(res);
1892-
return res;
1893-
}
1894-
PyErr_Format(PyExc_TypeError,
1895-
"can't compare %.200s to %.200s",
1896-
Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1897-
return NULL;
1898-
}
1899-
if (((result = (IDENT_CAST)(s->e.ident - o->e.ident)) == 0) &&
1900-
((result = s->e.filter - o->e.filter) == 0) &&
1901-
((result = s->e.flags - o->e.flags) == 0) &&
1902-
((result = (int)(s->e.fflags - o->e.fflags)) == 0) &&
1903-
((result = s->e.data - o->e.data) == 0) &&
1904-
((result = s->e.udata - o->e.udata) == 0)
1905-
) {
1906-
result = 0;
1907-
}
1920+
Py_RETURN_NOTIMPLEMENTED;
1921+
}
1922+
1923+
#define CMP(a, b) ((a) != (b)) ? ((a) < (b) ? -1 : 1)
1924+
result = CMP(s->e.ident, o->e.ident)
1925+
: CMP(s->e.filter, o->e.filter)
1926+
: CMP(s->e.flags, o->e.flags)
1927+
: CMP(s->e.fflags, o->e.fflags)
1928+
: CMP(s->e.data, o->e.data)
1929+
: CMP((intptr_t)s->e.udata, (intptr_t)o->e.udata)
1930+
: 0;
1931+
#undef CMP
19081932

19091933
switch (op) {
19101934
case Py_EQ:

0 commit comments

Comments
 (0)
0