Commit f919054e authored by Dino Viehland's avatar Dino Viehland Committed by GitHub

bpo-38116: Convert select module to PEP-384 (#15971)

* Convert select module to PEP-384

Summary: Do the necessary versions to be Pyro-compatible, including migrating `PyType_Ready` to `PyType_FromSpec` and moving static data into a new `_selectstate` struct.

* 📜🤖 Added by blurb_it.

* Fixup Mac OS/X build
parent 0247e80f
The select module is now PEP-384 compliant and no longer has static state
\ No newline at end of file
...@@ -959,11 +959,11 @@ select_kqueue(PyTypeObject *type, PyObject *args, PyObject *kwargs) ...@@ -959,11 +959,11 @@ select_kqueue(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{ {
PyObject *return_value = NULL; PyObject *return_value = NULL;
if ((type == &kqueue_queue_Type) && if ((type == _selectstate_global->kqueue_queue_Type) &&
!_PyArg_NoPositional("kqueue", args)) { !_PyArg_NoPositional("kqueue", args)) {
goto exit; goto exit;
} }
if ((type == &kqueue_queue_Type) && if ((type == _selectstate_global->kqueue_queue_Type) &&
!_PyArg_NoKeywords("kqueue", kwargs)) { !_PyArg_NoKeywords("kqueue", kwargs)) {
goto exit; goto exit;
} }
...@@ -1215,4 +1215,4 @@ exit: ...@@ -1215,4 +1215,4 @@ exit:
#ifndef SELECT_KQUEUE_CONTROL_METHODDEF #ifndef SELECT_KQUEUE_CONTROL_METHODDEF
#define SELECT_KQUEUE_CONTROL_METHODDEF #define SELECT_KQUEUE_CONTROL_METHODDEF
#endif /* !defined(SELECT_KQUEUE_CONTROL_METHODDEF) */ #endif /* !defined(SELECT_KQUEUE_CONTROL_METHODDEF) */
/*[clinic end generated code: output=03041f3d09b04a3d input=a9049054013a1b77]*/ /*[clinic end generated code: output=26bb05e5fba2bfd1 input=a9049054013a1b77]*/
...@@ -58,14 +58,28 @@ extern void bzero(void *, int); ...@@ -58,14 +58,28 @@ extern void bzero(void *, int);
# define SOCKET int # define SOCKET int
#endif #endif
typedef struct {
PyObject *close;
PyTypeObject *poll_Type;
PyTypeObject *devpoll_Type;
PyTypeObject *pyEpoll_Type;
PyTypeObject *kqueue_event_Type;
PyTypeObject *kqueue_queue_Type;
} _selectstate;
static struct PyModuleDef selectmodule;
#define _selectstate(o) ((_selectstate *)PyModule_GetState(o))
#define _selectstate_global _selectstate(PyState_FindModule(&selectmodule))
/*[clinic input] /*[clinic input]
module select module select
class select.poll "pollObject *" "&poll_Type" class select.poll "pollObject *" "&poll_Type"
class select.devpoll "devpollObject *" "&devpoll_Type" class select.devpoll "devpollObject *" "&devpoll_Type"
class select.epoll "pyEpoll_Object *" "&pyEpoll_Type" class select.epoll "pyEpoll_Object *" "&pyEpoll_Type"
class select.kqueue "kqueue_queue_Object *" "&kqueue_queue_Type" class select.kqueue "kqueue_queue_Object *" "_selectstate_global->kqueue_queue_Type"
[clinic start generated code]*/ [clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ded80abdad2b7552]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=41071028e0ede093]*/
static int static int
fildes_converter(PyObject *o, void *p) fildes_converter(PyObject *o, void *p)
...@@ -400,8 +414,6 @@ typedef struct { ...@@ -400,8 +414,6 @@ typedef struct {
int poll_running; int poll_running;
} pollObject; } pollObject;
static PyTypeObject poll_Type;
/* Update the malloc'ed array of pollfds to match the dictionary /* Update the malloc'ed array of pollfds to match the dictionary
contained within a pollObject. Return 1 on success, 0 on an error. contained within a pollObject. Return 1 on success, 0 on an error.
*/ */
...@@ -709,7 +721,7 @@ static pollObject * ...@@ -709,7 +721,7 @@ static pollObject *
newPollObject(void) newPollObject(void)
{ {
pollObject *self; pollObject *self;
self = PyObject_New(pollObject, &poll_Type); self = PyObject_New(pollObject, _selectstate_global->poll_Type);
if (self == NULL) if (self == NULL)
return NULL; return NULL;
/* ufd_uptodate is a Boolean, denoting whether the /* ufd_uptodate is a Boolean, denoting whether the
...@@ -725,13 +737,22 @@ newPollObject(void) ...@@ -725,13 +737,22 @@ newPollObject(void)
return self; return self;
} }
static PyObject *
poll_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{
PyErr_Format(PyExc_TypeError, "Cannot create '%.200s' instances", _PyType_Name(type));
return NULL;
}
static void static void
poll_dealloc(pollObject *self) poll_dealloc(pollObject *self)
{ {
PyObject* type = (PyObject *)Py_TYPE(self);
if (self->ufds != NULL) if (self->ufds != NULL)
PyMem_DEL(self->ufds); PyMem_DEL(self->ufds);
Py_XDECREF(self->dict); Py_XDECREF(self->dict);
PyObject_Del(self); PyObject_Del(self);
Py_DECREF(type);
} }
...@@ -744,8 +765,6 @@ typedef struct { ...@@ -744,8 +765,6 @@ typedef struct {
struct pollfd *fds; struct pollfd *fds;
} devpollObject; } devpollObject;
static PyTypeObject devpoll_Type;
static PyObject * static PyObject *
devpoll_err_closed(void) devpoll_err_closed(void)
{ {
...@@ -1091,7 +1110,7 @@ newDevPollObject(void) ...@@ -1091,7 +1110,7 @@ newDevPollObject(void)
return NULL; return NULL;
} }
self = PyObject_New(devpollObject, &devpoll_Type); self = PyObject_New(devpollObject, _selectstate_global->devpoll_Type);
if (self == NULL) { if (self == NULL) {
close(fd_devpoll); close(fd_devpoll);
PyMem_DEL(fds); PyMem_DEL(fds);
...@@ -1105,14 +1124,39 @@ newDevPollObject(void) ...@@ -1105,14 +1124,39 @@ newDevPollObject(void)
return self; return self;
} }
static PyObject *
devpoll_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{
PyErr_Format(PyExc_TypeError, "Cannot create '%.200s' instances", _PyType_Name(type));
return NULL;
}
static void static void
devpoll_dealloc(devpollObject *self) devpoll_dealloc(devpollObject *self)
{ {
PyObject *type = (PyObject *)Py_TYPE(self);
(void)devpoll_internal_close(self); (void)devpoll_internal_close(self);
PyMem_DEL(self->fds); PyMem_DEL(self->fds);
PyObject_Del(self); PyObject_Del(self);
Py_DECREF(type);
} }
static PyType_Slot devpoll_Type_slots[] = {
{Py_tp_dealloc, devpoll_dealloc},
{Py_tp_getset, devpoll_getsetlist},
{Py_tp_methods, devpoll_methods},
{Py_tp_new, devpoll_new},
{0, 0},
};
static PyType_Spec devpoll_Type_spec = {
"select.devpoll",
sizeof(devpollObject),
0,
Py_TPFLAGS_DEFAULT,
devpoll_Type_slots
};
#endif /* HAVE_SYS_DEVPOLL_H */ #endif /* HAVE_SYS_DEVPOLL_H */
...@@ -1201,8 +1245,7 @@ typedef struct { ...@@ -1201,8 +1245,7 @@ typedef struct {
SOCKET epfd; /* epoll control file descriptor */ SOCKET epfd; /* epoll control file descriptor */
} pyEpoll_Object; } pyEpoll_Object;
static PyTypeObject pyEpoll_Type; #define pyepoll_CHECK(op) (PyObject_TypeCheck((op), _selectstate_global->pyEpoll_Type))
#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
static PyObject * static PyObject *
pyepoll_err_closed(void) pyepoll_err_closed(void)
...@@ -1230,9 +1273,10 @@ static PyObject * ...@@ -1230,9 +1273,10 @@ static PyObject *
newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd) newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
{ {
pyEpoll_Object *self; pyEpoll_Object *self;
assert(type != NULL);
assert(type != NULL && type->tp_alloc != NULL); allocfunc epoll_alloc = PyType_GetSlot(type, Py_tp_alloc);
self = (pyEpoll_Object *) type->tp_alloc(type, 0); assert(epoll_alloc != NULL);
self = (pyEpoll_Object *) epoll_alloc(type, 0);
if (self == NULL) if (self == NULL)
return NULL; return NULL;
...@@ -1307,8 +1351,11 @@ select_epoll_impl(PyTypeObject *type, int sizehint, int flags) ...@@ -1307,8 +1351,11 @@ select_epoll_impl(PyTypeObject *type, int sizehint, int flags)
static void static void
pyepoll_dealloc(pyEpoll_Object *self) pyepoll_dealloc(pyEpoll_Object *self)
{ {
PyTypeObject* type = Py_TYPE(self);
(void)pyepoll_internal_close(self); (void)pyepoll_internal_close(self);
Py_TYPE(self)->tp_free(self); freefunc epoll_free = PyType_GetSlot(type, Py_tp_free);
epoll_free((PyObject *)self);
Py_DECREF((PyObject *)type);
} }
/*[clinic input] /*[clinic input]
...@@ -1632,9 +1679,7 @@ select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type, ...@@ -1632,9 +1679,7 @@ select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type,
PyObject *exc_value, PyObject *exc_tb) PyObject *exc_value, PyObject *exc_tb)
/*[clinic end generated code: output=c480f38ce361748e input=7ae81a5a4c1a98d8]*/ /*[clinic end generated code: output=c480f38ce361748e input=7ae81a5a4c1a98d8]*/
{ {
_Py_IDENTIFIER(close); return PyObject_CallMethodObjArgs((PyObject *)self, _selectstate_global->close, NULL);
return _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_close);
} }
static PyGetSetDef pyepoll_getsetlist[] = { static PyGetSetDef pyepoll_getsetlist[] = {
...@@ -1643,6 +1688,15 @@ static PyGetSetDef pyepoll_getsetlist[] = { ...@@ -1643,6 +1688,15 @@ static PyGetSetDef pyepoll_getsetlist[] = {
{0}, {0},
}; };
PyDoc_STRVAR(pyepoll_doc,
"select.epoll(sizehint=-1, flags=0)\n\
\n\
Returns an epolling object\n\
\n\
sizehint must be a positive integer or -1 for the default size. The\n\
sizehint is used to optimize internal data structures. It doesn't limit\n\
the maximum number of monitored events.");
#endif /* HAVE_EPOLL */ #endif /* HAVE_EPOLL */
#ifdef HAVE_KQUEUE #ifdef HAVE_KQUEUE
...@@ -1699,18 +1753,14 @@ typedef struct { ...@@ -1699,18 +1753,14 @@ typedef struct {
struct kevent e; struct kevent e;
} kqueue_event_Object; } kqueue_event_Object;
static PyTypeObject kqueue_event_Type; #define kqueue_event_Check(op) (PyObject_TypeCheck((op), _selectstate_global->kqueue_event_Type))
#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
SOCKET kqfd; /* kqueue control fd */ SOCKET kqfd; /* kqueue control fd */
} kqueue_queue_Object; } kqueue_queue_Object;
static PyTypeObject kqueue_queue_Type; #define kqueue_queue_Check(op) (PyObject_TypeCheck((op), _selectstate_global->kqueue_queue_Type))
#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P) #if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
# error uintptr_t does not match void *! # error uintptr_t does not match void *!
...@@ -1870,6 +1920,24 @@ kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o, ...@@ -1870,6 +1920,24 @@ kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Py_RETURN_RICHCOMPARE(result, 0, op); Py_RETURN_RICHCOMPARE(result, 0, op);
} }
static PyType_Slot kqueue_event_Type_slots[] = {
{Py_tp_doc, (void*)kqueue_event_doc},
{Py_tp_init, kqueue_event_init},
{Py_tp_members, kqueue_event_members},
{Py_tp_new, PyType_GenericNew},
{Py_tp_repr, kqueue_event_repr},
{Py_tp_richcompare, kqueue_event_richcompare},
{0, 0},
};
static PyType_Spec kqueue_event_Type_spec = {
"select.kevent",
sizeof(kqueue_event_Object),
0,
Py_TPFLAGS_DEFAULT,
kqueue_event_Type_slots
};
static PyObject * static PyObject *
kqueue_queue_err_closed(void) kqueue_queue_err_closed(void)
{ {
...@@ -1896,8 +1964,10 @@ static PyObject * ...@@ -1896,8 +1964,10 @@ static PyObject *
newKqueue_Object(PyTypeObject *type, SOCKET fd) newKqueue_Object(PyTypeObject *type, SOCKET fd)
{ {
kqueue_queue_Object *self; kqueue_queue_Object *self;
assert(type != NULL && type->tp_alloc != NULL); assert(type != NULL);
self = (kqueue_queue_Object *) type->tp_alloc(type, 0); allocfunc queue_alloc = PyType_GetSlot(type, Py_tp_alloc);
assert(queue_alloc != NULL);
self = (kqueue_queue_Object *) queue_alloc(type, 0);
if (self == NULL) { if (self == NULL) {
return NULL; return NULL;
} }
...@@ -1954,8 +2024,11 @@ select_kqueue_impl(PyTypeObject *type) ...@@ -1954,8 +2024,11 @@ select_kqueue_impl(PyTypeObject *type)
static void static void
kqueue_queue_dealloc(kqueue_queue_Object *self) kqueue_queue_dealloc(kqueue_queue_Object *self)
{ {
PyTypeObject* type = Py_TYPE(self);
kqueue_queue_internal_close(self); kqueue_queue_internal_close(self);
Py_TYPE(self)->tp_free(self); freefunc kqueue_free = PyType_GetSlot(type, Py_tp_free);
kqueue_free((PyObject *)self);
Py_DECREF((PyObject *)type);
} }
/*[clinic input] /*[clinic input]
...@@ -2072,7 +2145,7 @@ select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist, ...@@ -2072,7 +2145,7 @@ select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist,
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"timeout argument must be a number " "timeout argument must be a number "
"or None, got %.200s", "or None, got %.200s",
Py_TYPE(otimeout)->tp_name); _PyType_Name(Py_TYPE(otimeout)));
return NULL; return NULL;
} }
...@@ -2168,7 +2241,7 @@ select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist, ...@@ -2168,7 +2241,7 @@ select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist,
for (i = 0; i < gotevents; i++) { for (i = 0; i < gotevents; i++) {
kqueue_event_Object *ch; kqueue_event_Object *ch;
ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type); ch = PyObject_New(kqueue_event_Object, _selectstate_global->kqueue_event_Type);
if (ch == NULL) { if (ch == NULL) {
goto error; goto error;
} }
...@@ -2210,38 +2283,20 @@ static PyMethodDef poll_methods[] = { ...@@ -2210,38 +2283,20 @@ static PyMethodDef poll_methods[] = {
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };
static PyTypeObject poll_Type = {
/* The ob_type field must be initialized in the module init function static PyType_Slot poll_Type_slots[] = {
* to be portable to Windows without using C++. */ {Py_tp_dealloc, poll_dealloc},
PyVarObject_HEAD_INIT(NULL, 0) {Py_tp_methods, poll_methods},
"select.poll", /*tp_name*/ {Py_tp_new, poll_new},
sizeof(pollObject), /*tp_basicsize*/ {0, 0},
0, /*tp_itemsize*/ };
/* methods */
(destructor)poll_dealloc, /*tp_dealloc*/ static PyType_Spec poll_Type_spec = {
0, /*tp_vectorcall_offset*/ "select.poll",
0, /*tp_getattr*/ sizeof(pollObject),
0, /*tp_setattr*/ 0,
0, /*tp_as_async*/ Py_TPFLAGS_DEFAULT,
0, /*tp_repr*/ poll_Type_slots
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash*/
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
0, /*tp_doc*/
0, /*tp_traverse*/
0, /*tp_clear*/
0, /*tp_richcompare*/
0, /*tp_weaklistoffset*/
0, /*tp_iter*/
0, /*tp_iternext*/
poll_methods, /*tp_methods*/
}; };
#ifdef HAVE_SYS_DEVPOLL_H #ifdef HAVE_SYS_DEVPOLL_H
...@@ -2256,42 +2311,6 @@ static PyMethodDef devpoll_methods[] = { ...@@ -2256,42 +2311,6 @@ static PyMethodDef devpoll_methods[] = {
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };
static PyTypeObject devpoll_Type = {
/* The ob_type field must be initialized in the module init function
* to be portable to Windows without using C++. */
PyVarObject_HEAD_INIT(NULL, 0)
"select.devpoll", /*tp_name*/
sizeof(devpollObject), /*tp_basicsize*/
0, /*tp_itemsize*/
/* methods */
(destructor)devpoll_dealloc, /*tp_dealloc*/
0, /*tp_vectorcall_offset*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_as_async*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash*/
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
0, /*tp_doc*/
0, /*tp_traverse*/
0, /*tp_clear*/
0, /*tp_richcompare*/
0, /*tp_weaklistoffset*/
0, /*tp_iter*/
0, /*tp_iternext*/
devpoll_methods, /*tp_methods*/
0, /* tp_members */
devpoll_getsetlist, /* tp_getset */
};
#endif /* HAVE_SYS_DEVPOLL_H */ #endif /* HAVE_SYS_DEVPOLL_H */
#endif /* HAVE_POLL */ #endif /* HAVE_POLL */
...@@ -2311,94 +2330,28 @@ static PyMethodDef pyepoll_methods[] = { ...@@ -2311,94 +2330,28 @@ static PyMethodDef pyepoll_methods[] = {
{NULL, NULL}, {NULL, NULL},
}; };
static PyTypeObject pyEpoll_Type = { static PyType_Slot pyEpoll_Type_slots[] = {
PyVarObject_HEAD_INIT(NULL, 0) {Py_tp_dealloc, pyepoll_dealloc},
"select.epoll", /* tp_name */ {Py_tp_doc, (void*)pyepoll_doc},
sizeof(pyEpoll_Object), /* tp_basicsize */ {Py_tp_getattro, PyObject_GenericGetAttr},
0, /* tp_itemsize */ {Py_tp_getset, pyepoll_getsetlist},
(destructor)pyepoll_dealloc, /* tp_dealloc */ {Py_tp_methods, pyepoll_methods},
0, /* tp_vectorcall_offset */ {Py_tp_new, select_epoll},
0, /* tp_getattr */ {0, 0},
0, /* tp_setattr */ };
0, /* tp_as_async */
0, /* tp_repr */ static PyType_Spec pyEpoll_Type_spec = {
0, /* tp_as_number */ "select.epoll",
0, /* tp_as_sequence */ sizeof(pyEpoll_Object),
0, /* tp_as_mapping */ 0,
0, /* tp_hash */ Py_TPFLAGS_DEFAULT,
0, /* tp_call */ pyEpoll_Type_slots
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
select_epoll__doc__, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
pyepoll_methods, /* tp_methods */
0, /* tp_members */
pyepoll_getsetlist, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
select_epoll, /* tp_new */
0, /* tp_free */
}; };
#endif /* HAVE_EPOLL */ #endif /* HAVE_EPOLL */
#ifdef HAVE_KQUEUE #ifdef HAVE_KQUEUE
static PyTypeObject kqueue_event_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"select.kevent", /* tp_name */
sizeof(kqueue_event_Object), /* tp_basicsize */
0, /* tp_itemsize */
0, /* tp_dealloc */
0, /* tp_vectorcall_offset */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_as_async */
(reprfunc)kqueue_event_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
kqueue_event_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
(richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
kqueue_event_members, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)kqueue_event_init, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
0, /* tp_free */
};
static PyMethodDef kqueue_queue_methods[] = { static PyMethodDef kqueue_queue_methods[] = {
SELECT_KQUEUE_FROMFD_METHODDEF SELECT_KQUEUE_FROMFD_METHODDEF
SELECT_KQUEUE_CLOSE_METHODDEF SELECT_KQUEUE_CLOSE_METHODDEF
...@@ -2407,46 +2360,21 @@ static PyMethodDef kqueue_queue_methods[] = { ...@@ -2407,46 +2360,21 @@ static PyMethodDef kqueue_queue_methods[] = {
{NULL, NULL}, {NULL, NULL},
}; };
static PyTypeObject kqueue_queue_Type = { static PyType_Slot kqueue_queue_Type_slots[] = {
PyVarObject_HEAD_INIT(NULL, 0) {Py_tp_dealloc, kqueue_queue_dealloc},
"select.kqueue", /* tp_name */ {Py_tp_doc, select_kqueue__doc__},
sizeof(kqueue_queue_Object), /* tp_basicsize */ {Py_tp_getset, kqueue_queue_getsetlist},
0, /* tp_itemsize */ {Py_tp_methods, kqueue_queue_methods},
(destructor)kqueue_queue_dealloc, /* tp_dealloc */ {Py_tp_new, select_kqueue},
0, /* tp_vectorcall_offset */ {0, 0},
0, /* tp_getattr */ };
0, /* tp_setattr */
0, /* tp_as_async */ static PyType_Spec kqueue_queue_Type_spec = {
0, /* tp_repr */ "select.kqueue",
0, /* tp_as_number */ sizeof(kqueue_queue_Object),
0, /* tp_as_sequence */ 0,
0, /* tp_as_mapping */ Py_TPFLAGS_DEFAULT,
0, /* tp_hash */ kqueue_queue_Type_slots
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
select_kqueue__doc__, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
kqueue_queue_methods, /* tp_methods */
0, /* tp_members */
kqueue_queue_getsetlist, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
select_kqueue, /* tp_new */
0, /* tp_free */
}; };
#endif /* HAVE_KQUEUE */ #endif /* HAVE_KQUEUE */
...@@ -2472,21 +2400,49 @@ PyDoc_STRVAR(module_doc, ...@@ -2472,21 +2400,49 @@ PyDoc_STRVAR(module_doc,
On Windows, only sockets are supported; on Unix, all file descriptors."); On Windows, only sockets are supported; on Unix, all file descriptors.");
static int
_select_traverse(PyObject *module, visitproc visit, void *arg)
{
Py_VISIT(_selectstate(module)->close);
Py_VISIT(_selectstate(module)->poll_Type);
Py_VISIT(_selectstate(module)->devpoll_Type);
Py_VISIT(_selectstate(module)->pyEpoll_Type);
Py_VISIT(_selectstate(module)->kqueue_event_Type);
Py_VISIT(_selectstate(module)->kqueue_queue_Type);
return 0;
}
static int
_select_clear(PyObject *module)
{
Py_CLEAR(_selectstate(module)->close);
Py_CLEAR(_selectstate(module)->poll_Type);
Py_CLEAR(_selectstate(module)->devpoll_Type);
Py_CLEAR(_selectstate(module)->pyEpoll_Type);
Py_CLEAR(_selectstate(module)->kqueue_event_Type);
Py_CLEAR(_selectstate(module)->kqueue_queue_Type);
return 0;
}
static void
_select_free(void *module)
{
_select_clear((PyObject *)module);
}
static struct PyModuleDef selectmodule = { static struct PyModuleDef selectmodule = {
PyModuleDef_HEAD_INIT, PyModuleDef_HEAD_INIT,
"select", "select",
module_doc, module_doc,
-1, sizeof(_selectstate),
select_methods, select_methods,
NULL, NULL,
NULL, _select_traverse,
NULL, _select_clear,
NULL _select_free,
}; };
PyMODINIT_FUNC PyMODINIT_FUNC
PyInit_select(void) PyInit_select(void)
{ {
...@@ -2495,6 +2451,8 @@ PyInit_select(void) ...@@ -2495,6 +2451,8 @@ PyInit_select(void)
if (m == NULL) if (m == NULL)
return NULL; return NULL;
_selectstate(m)->close = PyUnicode_InternFromString("close");
Py_INCREF(PyExc_OSError); Py_INCREF(PyExc_OSError);
PyModule_AddObject(m, "error", PyExc_OSError); PyModule_AddObject(m, "error", PyExc_OSError);
...@@ -2516,8 +2474,12 @@ PyInit_select(void) ...@@ -2516,8 +2474,12 @@ PyInit_select(void)
#else #else
{ {
#endif #endif
if (PyType_Ready(&poll_Type) < 0) PyObject *poll_Type = PyType_FromSpec(&poll_Type_spec);
if (poll_Type == NULL)
return NULL; return NULL;
_selectstate(m)->poll_Type = (PyTypeObject *)poll_Type;
Py_INCREF(poll_Type);
PyModule_AddIntMacro(m, POLLIN); PyModule_AddIntMacro(m, POLLIN);
PyModule_AddIntMacro(m, POLLPRI); PyModule_AddIntMacro(m, POLLPRI);
PyModule_AddIntMacro(m, POLLOUT); PyModule_AddIntMacro(m, POLLOUT);
...@@ -2548,17 +2510,20 @@ PyInit_select(void) ...@@ -2548,17 +2510,20 @@ PyInit_select(void)
#endif /* HAVE_POLL */ #endif /* HAVE_POLL */
#ifdef HAVE_SYS_DEVPOLL_H #ifdef HAVE_SYS_DEVPOLL_H
if (PyType_Ready(&devpoll_Type) < 0) PyObject *devpoll_Type = PyType_FromSpec(&devpoll_Type_spec);
if (devpoll_Type == NULL)
return NULL; return NULL;
_selectstate(m)->devpoll_Type = (PyTypeObject *)devpoll_Type;
Py_INCREF(devpoll_Type);
#endif #endif
#ifdef HAVE_EPOLL #ifdef HAVE_EPOLL
Py_TYPE(&pyEpoll_Type) = &PyType_Type; PyObject *pyEpoll_Type = PyType_FromSpec(&pyEpoll_Type_spec);
if (PyType_Ready(&pyEpoll_Type) < 0) if (pyEpoll_Type == NULL)
return NULL; return NULL;
_selectstate(m)->pyEpoll_Type = (PyTypeObject *)pyEpoll_Type;
Py_INCREF(&pyEpoll_Type); Py_INCREF(pyEpoll_Type);
PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type); PyModule_AddObject(m, "epoll", (PyObject *)_selectstate(m)->pyEpoll_Type);
PyModule_AddIntMacro(m, EPOLLIN); PyModule_AddIntMacro(m, EPOLLIN);
PyModule_AddIntMacro(m, EPOLLOUT); PyModule_AddIntMacro(m, EPOLLOUT);
...@@ -2600,19 +2565,19 @@ PyInit_select(void) ...@@ -2600,19 +2565,19 @@ PyInit_select(void)
#endif /* HAVE_EPOLL */ #endif /* HAVE_EPOLL */
#ifdef HAVE_KQUEUE #ifdef HAVE_KQUEUE
kqueue_event_Type.tp_new = PyType_GenericNew; PyObject *kqueue_event_Type = PyType_FromSpec(&kqueue_event_Type_spec);
Py_TYPE(&kqueue_event_Type) = &PyType_Type; if (kqueue_event_Type == NULL)
if(PyType_Ready(&kqueue_event_Type) < 0)
return NULL; return NULL;
_selectstate(m)->kqueue_event_Type = (PyTypeObject *)kqueue_event_Type;
Py_INCREF(_selectstate(m)->kqueue_event_Type);
PyModule_AddObject(m, "kevent", kqueue_event_Type);
Py_INCREF(&kqueue_event_Type); PyObject *kqueue_queue_Type = PyType_FromSpec(&kqueue_queue_Type_spec);
PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type); if (kqueue_queue_Type == NULL)
Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
if(PyType_Ready(&kqueue_queue_Type) < 0)
return NULL; return NULL;
Py_INCREF(&kqueue_queue_Type); _selectstate(m)->kqueue_queue_Type = (PyTypeObject *)kqueue_queue_Type;
PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type); Py_INCREF(_selectstate(m)->kqueue_queue_Type);
PyModule_AddObject(m, "kqueue", kqueue_queue_Type);
/* event filters */ /* event filters */
PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ); PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment