From 391f2430834ef464e4b166a1f84fd6c1b01b26e2 Mon Sep 17 00:00:00 2001 From: Tal Einat Date: Sat, 28 Oct 2017 21:48:49 +0300 Subject: [PATCH 01/17] bpo-20182: initial application of issue20182.selectmodule.v2.patch Not in working condition, things need to be moved around to work with generation of AC code in a separate file. --- Modules/clinic/selectmodule.c.h | 589 ++++++++++++++++++++++++++++++++ Modules/selectmodule.c | 526 +++++++++++++++------------- 2 files changed, 873 insertions(+), 242 deletions(-) create mode 100644 Modules/clinic/selectmodule.c.h diff --git a/Modules/clinic/selectmodule.c.h b/Modules/clinic/selectmodule.c.h new file mode 100644 index 00000000000000..80208ef972d547 --- /dev/null +++ b/Modules/clinic/selectmodule.c.h @@ -0,0 +1,589 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(select_select__doc__, +"select($module, rlist, wlist, xlist, timeout=None, /)\n" +"--\n" +"\n" +"Wait until one or more file descriptors are ready for some kind of I/O.\n" +"\n" +"The first three arguments are sequences of file descriptors to be waited for:\n" +" rlist -- wait until ready for reading\n" +" wlist -- wait until ready for writing\n" +" xlist -- wait for an ``exceptional condition\'\'\n" +"If only one kind of condition is required, pass [] for the other lists.\n" +"A file descriptor is either a socket or file object, or a small integer\n" +"gotten from a fileno() method call on one of those.\n" +"\n" +"The optional 4th argument specifies a timeout in seconds; it may be\n" +"a floating point number to specify fractions of seconds. If it is absent\n" +"or None, the call will never time out.\n" +"\n" +"The return value is a tuple of three lists corresponding to the first three\n" +"arguments; each contains the subset of the corresponding file descriptors\n" +"that are ready.\n" +"\n" +"*** IMPORTANT NOTICE ***\n" +"On Windows only sockets are supported; on Unix, all file descriptors\n" +"can be used."); + +#define SELECT_SELECT_METHODDEF \ + {"select", (PyCFunction)select_select, METH_VARARGS, select_select__doc__}, + +static PyObject * +select_select_impl(PyModuleDef *module, PyObject *rlist, PyObject *wlist, + PyObject *xlist, PyObject *timeout_obj); + +static PyObject * +select_select(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *rlist; + PyObject *wlist; + PyObject *xlist; + PyObject *timeout_obj = Py_None; + + if (!PyArg_UnpackTuple(args, "select", + 3, 4, + &rlist, &wlist, &xlist, &timeout_obj)) + goto exit; + return_value = select_select_impl(module, rlist, wlist, xlist, timeout_obj); + +exit: + return return_value; +} + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) + +PyDoc_STRVAR(select_poll_register__doc__, +"register($self, fd,\n" +" eventmask=select.POLLIN | select.POLLPRI | select.POLLOUT, /)\n" +"--\n" +"\n" +"Register a file descriptor with the polling object.\n" +"\n" +" fd\n" +" either an integer, or an object with a fileno() method returning\n" +" an int\n" +" eventmask\n" +" an optional bitmask describing the type of events to check for"); + +#define SELECT_POLL_REGISTER_METHODDEF \ + {"register", (PyCFunction)select_poll_register, METH_VARARGS, select_poll_register__doc__}, + +static PyObject * +select_poll_register_impl(pollObject *self, PyObject *fd, + unsigned short eventmask); + +static PyObject * +select_poll_register(pollObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *fd; + unsigned short eventmask = POLLIN | POLLPRI | POLLOUT; + + if (!PyArg_ParseTuple(args, "O|O&:register", + &fd, ushort_converter, &eventmask)) + goto exit; + return_value = select_poll_register_impl(self, fd, eventmask); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) + +PyDoc_STRVAR(select_poll_modify__doc__, +"modify($self, fd, eventmask, /)\n" +"--\n" +"\n" +"Modify an already registered file descriptor.\n" +"\n" +" fd\n" +" either an integer, or an object with a fileno() method returning\n" +" an int\n" +" eventmask\n" +" an optional bitmask describing the type of events to check for"); + +#define SELECT_POLL_MODIFY_METHODDEF \ + {"modify", (PyCFunction)select_poll_modify, METH_VARARGS, select_poll_modify__doc__}, + +static PyObject * +select_poll_modify_impl(pollObject *self, PyObject *fd, + unsigned short eventmask); + +static PyObject * +select_poll_modify(pollObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *fd; + unsigned short eventmask; + + if (!PyArg_ParseTuple(args, "OO&:modify", + &fd, ushort_converter, &eventmask)) + goto exit; + return_value = select_poll_modify_impl(self, fd, eventmask); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) + +PyDoc_STRVAR(select_poll_unregister__doc__, +"unregister($self, fd, /)\n" +"--\n" +"\n" +"Remove a file descriptor being tracked by the polling object."); + +#define SELECT_POLL_UNREGISTER_METHODDEF \ + {"unregister", (PyCFunction)select_poll_unregister, METH_O, select_poll_unregister__doc__}, + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) + +PyDoc_STRVAR(select_poll_poll__doc__, +"poll($self, timeout=None, /)\n" +"--\n" +"\n" +"Polls the set of registered file descriptors.\n" +"\n" +"Return value is a list containing any descriptors that have events\n" +"or errors to report, in the form of tuples (fd, event)."); + +#define SELECT_POLL_POLL_METHODDEF \ + {"poll", (PyCFunction)select_poll_poll, METH_VARARGS, select_poll_poll__doc__}, + +static PyObject * +select_poll_poll_impl(pollObject *self, PyObject *timeout_obj); + +static PyObject * +select_poll_poll(pollObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *timeout_obj = Py_None; + + if (!PyArg_UnpackTuple(args, "poll", + 0, 1, + &timeout_obj)) + goto exit; + return_value = select_poll_poll_impl(self, timeout_obj); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) + +PyDoc_STRVAR(select_poll__doc__, +"poll($module, /)\n" +"--\n" +"\n" +"Returns a polling object.\n" +"\n" +"The object supports registering and unregistering file descriptors,\n" +"and then polling them for I/O events."); + +#define SELECT_POLL_METHODDEF \ + {"poll", (PyCFunction)select_poll, METH_NOARGS, select_poll__doc__}, + +static PyObject * +select_poll_impl(PyModuleDef *module); + +static PyObject * +select_poll(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return select_poll_impl(module); +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) + +PyDoc_STRVAR(select_devpoll__doc__, +"devpoll($module, /)\n" +"--\n" +"\n" +"Returns a polling object using /dev/poll.\n" +"\n" +"The object supports registering and unregistering file descriptors,\n" +"and then polling them for I/O events."); + +#define SELECT_DEVPOLL_METHODDEF \ + {"devpoll", (PyCFunction)select_devpoll, METH_NOARGS, select_devpoll__doc__}, + +static PyObject * +select_devpoll_impl(PyModuleDef *module); + +static PyObject * +select_devpoll(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return select_devpoll_impl(module); +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(pyepoll_new__doc__, +"epoll(sizehint=-1, flags=0)\n" +"--\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."); + +static PyObject * +pyepoll_new_impl(PyTypeObject *type, int sizehint, int flags); + +static PyObject * +pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"sizehint", "flags", NULL}; + int sizehint = FD_SETSIZE - 1; + int flags = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii:epoll", _keywords, + &sizehint, &flags)) + goto exit; + return_value = pyepoll_new_impl(type, sizehint, flags); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(pyepoll_close__doc__, +"close($self, /)\n" +"--\n" +"\n" +"Close the epoll control file descriptor.\n" +"\n" +"Further operations on the epoll object will raise an exception."); + +#define PYEPOLL_CLOSE_METHODDEF \ + {"close", (PyCFunction)pyepoll_close, METH_NOARGS, pyepoll_close__doc__}, + +static PyObject * +pyepoll_close_impl(pyEpoll_Object *self); + +static PyObject * +pyepoll_close(pyEpoll_Object *self, PyObject *Py_UNUSED(ignored)) +{ + return pyepoll_close_impl(self); +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(pyepoll_fileno__doc__, +"fileno($self, /)\n" +"--\n" +"\n" +"Return the epoll control file descriptor."); + +#define PYEPOLL_FILENO_METHODDEF \ + {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS, pyepoll_fileno__doc__}, + +static PyObject * +pyepoll_fileno_impl(pyEpoll_Object *self); + +static PyObject * +pyepoll_fileno(pyEpoll_Object *self, PyObject *Py_UNUSED(ignored)) +{ + return pyepoll_fileno_impl(self); +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(pyepoll_fromfd__doc__, +"fromfd($type, fd, /)\n" +"--\n" +"\n" +"Create an epoll object from a given control fd."); + +#define PYEPOLL_FROMFD_METHODDEF \ + {"fromfd", (PyCFunction)pyepoll_fromfd, METH_O|METH_CLASS, pyepoll_fromfd__doc__}, + +static PyObject * +pyepoll_fromfd_impl(PyTypeObject *type, int fd); + +static PyObject * +pyepoll_fromfd(PyTypeObject *type, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + + if (!PyArg_Parse(arg, "i:fromfd", &fd)) + goto exit; + return_value = pyepoll_fromfd_impl(type, fd); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(pyepoll_register__doc__, +"register($self, /, fd,\n" +" eventmask=select.EPOLLIN | select.EPOLLOUT | select.EPOLLPRI)\n" +"--\n" +"\n" +"Registers a new fd or raises an OSError if the fd is already registered.\n" +"\n" +"fd is the target file descriptor of the operation.\n" +"events is a bit set composed of the various EPOLL constants; the default\n" +"is EPOLLIN | EPOLLOUT | EPOLLPRI.\n" +"\n" +"The epoll interface supports all file descriptors that support poll."); + +#define PYEPOLL_REGISTER_METHODDEF \ + {"register", (PyCFunction)pyepoll_register, METH_VARARGS|METH_KEYWORDS, pyepoll_register__doc__}, + +static PyObject * +pyepoll_register_impl(pyEpoll_Object *self, PyObject *fd, + unsigned int eventmask); + +static PyObject * +pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", "eventmask", NULL}; + PyObject *fd; + unsigned int eventmask = EPOLLIN | EPOLLOUT | EPOLLPRI; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|I:register", _keywords, + &fd, &eventmask)) + goto exit; + return_value = pyepoll_register_impl(self, fd, eventmask); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(pyepoll_modify__doc__, +"modify($self, /, fd, eventmask)\n" +"--\n" +"\n" +"Modify event mask for a registered file descriptor.\n" +"\n" +"fd is the target file descriptor of the operation, and\n" +"events is a bit set composed of the various EPOLL constants."); + +#define PYEPOLL_MODIFY_METHODDEF \ + {"modify", (PyCFunction)pyepoll_modify, METH_VARARGS|METH_KEYWORDS, pyepoll_modify__doc__}, + +static PyObject * +pyepoll_modify_impl(pyEpoll_Object *self, PyObject *fd, + unsigned int eventmask); + +static PyObject * +pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", "eventmask", NULL}; + PyObject *fd; + unsigned int eventmask; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OI:modify", _keywords, + &fd, &eventmask)) + goto exit; + return_value = pyepoll_modify_impl(self, fd, eventmask); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(pyepoll_unregister__doc__, +"unregister($self, /, fd)\n" +"--\n" +"\n" +"Remove a registered file descriptor from the epoll object.\n" +"\n" +"fd is the target file descriptor of the operation."); + +#define PYEPOLL_UNREGISTER_METHODDEF \ + {"unregister", (PyCFunction)pyepoll_unregister, METH_VARARGS|METH_KEYWORDS, pyepoll_unregister__doc__}, + +static PyObject * +pyepoll_unregister_impl(pyEpoll_Object *self, PyObject *fd); + +static PyObject * +pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", NULL}; + PyObject *fd; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:unregister", _keywords, + &fd)) + goto exit; + return_value = pyepoll_unregister_impl(self, fd); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(pyepoll_poll__doc__, +"poll($self, /, timeout=-1.0, maxevents=-1)\n" +"--\n" +"\n" +"Wait for events on the epoll file descriptor.\n" +"\n" +"timeout gives the maximum time to wait in seconds (as float).\n" +"A timeout of -1 makes poll wait indefinitely.\n" +"Up to maxevents are returned to the caller.\n" +"\n" +"The return value is a list of tuples of the form (fd, events)."); + +#define PYEPOLL_POLL_METHODDEF \ + {"poll", (PyCFunction)pyepoll_poll, METH_VARARGS|METH_KEYWORDS, pyepoll_poll__doc__}, + +static PyObject * +pyepoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj, int maxevents); + +static PyObject * +pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"timeout", "maxevents", NULL}; + PyObject *timeout_obj = Py_None; + int maxevents = -1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:poll", _keywords, + &timeout_obj, &maxevents)) + goto exit; + return_value = pyepoll_poll_impl(self, timeout_obj, maxevents); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(pyepoll_enter__doc__, +"__enter__($self, /)\n" +"--\n" +"\n"); + +#define PYEPOLL_ENTER_METHODDEF \ + {"__enter__", (PyCFunction)pyepoll_enter, METH_NOARGS, pyepoll_enter__doc__}, + +static PyObject * +pyepoll_enter_impl(pyEpoll_Object *self); + +static PyObject * +pyepoll_enter(pyEpoll_Object *self, PyObject *Py_UNUSED(ignored)) +{ + return pyepoll_enter_impl(self); +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(pyepoll_exit__doc__, +"__exit__($self, exc_type=None, exc_value=None, exc_tb=None, /)\n" +"--\n" +"\n"); + +#define PYEPOLL_EXIT_METHODDEF \ + {"__exit__", (PyCFunction)pyepoll_exit, METH_VARARGS, pyepoll_exit__doc__}, + +static PyObject * +pyepoll_exit_impl(pyEpoll_Object *self, PyObject *exc_type, + PyObject *exc_value, PyObject *exc_tb); + +static PyObject * +pyepoll_exit(pyEpoll_Object *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *exc_type = Py_None; + PyObject *exc_value = Py_None; + PyObject *exc_tb = Py_None; + + if (!PyArg_UnpackTuple(args, "__exit__", + 0, 3, + &exc_type, &exc_value, &exc_tb)) + goto exit; + return_value = pyepoll_exit_impl(self, exc_type, exc_value, exc_tb); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EPOLL) */ + +#ifndef SELECT_POLL_REGISTER_METHODDEF + #define SELECT_POLL_REGISTER_METHODDEF +#endif /* !defined(SELECT_POLL_REGISTER_METHODDEF) */ + +#ifndef SELECT_POLL_MODIFY_METHODDEF + #define SELECT_POLL_MODIFY_METHODDEF +#endif /* !defined(SELECT_POLL_MODIFY_METHODDEF) */ + +#ifndef SELECT_POLL_UNREGISTER_METHODDEF + #define SELECT_POLL_UNREGISTER_METHODDEF +#endif /* !defined(SELECT_POLL_UNREGISTER_METHODDEF) */ + +#ifndef SELECT_POLL_POLL_METHODDEF + #define SELECT_POLL_POLL_METHODDEF +#endif /* !defined(SELECT_POLL_POLL_METHODDEF) */ + +#ifndef SELECT_DEVPOLL_METHODDEF + #define SELECT_DEVPOLL_METHODDEF +#endif /* !defined(SELECT_DEVPOLL_METHODDEF) */ + +#ifndef PYEPOLL_CLOSE_METHODDEF + #define PYEPOLL_CLOSE_METHODDEF +#endif /* !defined(PYEPOLL_CLOSE_METHODDEF) */ + +#ifndef PYEPOLL_FILENO_METHODDEF + #define PYEPOLL_FILENO_METHODDEF +#endif /* !defined(PYEPOLL_FILENO_METHODDEF) */ + +#ifndef PYEPOLL_FROMFD_METHODDEF + #define PYEPOLL_FROMFD_METHODDEF +#endif /* !defined(PYEPOLL_FROMFD_METHODDEF) */ + +#ifndef PYEPOLL_ENTER_METHODDEF + #define PYEPOLL_ENTER_METHODDEF +#endif /* !defined(PYEPOLL_ENTER_METHODDEF) */ + +#ifndef PYEPOLL_EXIT_METHODDEF + #define PYEPOLL_EXIT_METHODDEF +#endif /* !defined(PYEPOLL_EXIT_METHODDEF) */ +/*[clinic end generated code: output=8c67fe108dc8d539 input=a9049054013a1b77]*/ diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index f2f5cc86cdbe51..a41c25972862e4 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -58,6 +58,16 @@ extern void bzero(void *, int); # define SOCKET int #endif +#include "clinic/selectmodule.c.h" + +/*[clinic input] +module select +class select.poll "pollObject *" "&poll_Type" +class select.epoll "pyEpoll_Object *" "&pyEpoll_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e04c459c99679db4]*/ + + /* list of Python objects and their file descriptor */ typedef struct { PyObject *obj; /* owned reference */ @@ -179,8 +189,41 @@ set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1]) #define SELECT_USES_HEAP #endif /* FD_SETSIZE > 1024 */ +/*[clinic input] +select.select + + rlist: object + wlist: object + xlist: object + timeout as timeout_obj: object = None + / + +Wait until one or more file descriptors are ready for some kind of I/O. +The first three arguments are sequences of file descriptors to be waited for: +rlist -- wait until ready for reading +wlist -- wait until ready for writing +xlist -- wait for an ``exceptional condition'' +If only one kind of condition is required, pass [] for the other lists. +A file descriptor is either a socket or file object, or a small integer +gotten from a fileno() method call on one of those. + +The optional 4th argument specifies a timeout in seconds; it may be +a floating point number to specify fractions of seconds. If it is absent +or None, the call will never time out. + +The return value is a tuple of three lists corresponding to the first three +arguments; each contains the subset of the corresponding file descriptors +that are ready. + +*** IMPORTANT NOTICE *** +On Windows, only sockets are supported; on Unix, all file +descriptors can be used. +[clinic start generated code]*/ + static PyObject * -select_select(PyObject *self, PyObject *args) +select_select_impl(PyModuleDef *module, PyObject *rlist, PyObject *wlist, + PyObject *xlist, PyObject *timeout_obj) +/*[clinic end generated code: output=7f9b92129e855343 input=7dc8f84d5d187916]*/ { #ifdef SELECT_USES_HEAP pylist *rfd2obj, *wfd2obj, *efd2obj; @@ -195,20 +238,13 @@ select_select(PyObject *self, PyObject *args) pylist wfd2obj[FD_SETSIZE + 1]; pylist efd2obj[FD_SETSIZE + 1]; #endif /* SELECT_USES_HEAP */ - PyObject *ifdlist, *ofdlist, *efdlist; PyObject *ret = NULL; - PyObject *timeout_obj = Py_None; fd_set ifdset, ofdset, efdset; struct timeval tv, *tvp; int imax, omax, emax, max; int n; _PyTime_t timeout, deadline = 0; - /* convert arguments */ - if (!PyArg_UnpackTuple(args, "select", 3, 4, - &ifdlist, &ofdlist, &efdlist, &timeout_obj)) - return NULL; - if (timeout_obj == Py_None) tvp = (struct timeval *)NULL; else { @@ -249,11 +285,11 @@ select_select(PyObject *self, PyObject *args) rfd2obj[0].sentinel = -1; wfd2obj[0].sentinel = -1; efd2obj[0].sentinel = -1; - if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0) + if ((imax = seq2set(rlist, &ifdset, rfd2obj)) < 0) goto finally; - if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0) + if ((omax = seq2set(wlist, &ofdset, wfd2obj)) < 0) goto finally; - if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0) + if ((emax = seq2set(xlist, &efdset, efd2obj)) < 0) goto finally; max = imax; @@ -301,17 +337,17 @@ select_select(PyObject *self, PyObject *args) convenient to test for this after all three calls... but is that acceptable? */ - ifdlist = set2list(&ifdset, rfd2obj); - ofdlist = set2list(&ofdset, wfd2obj); - efdlist = set2list(&efdset, efd2obj); + rlist = set2list(&ifdset, rfd2obj); + wlist = set2list(&ofdset, wfd2obj); + xlist = set2list(&efdset, efd2obj); if (PyErr_Occurred()) ret = NULL; else - ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist); + ret = PyTuple_Pack(3, rlist, wlist, xlist); - Py_XDECREF(ifdlist); - Py_XDECREF(ofdlist); - Py_XDECREF(efdlist); + Py_XDECREF(rlist); + Py_XDECREF(wlist); + Py_XDECREF(xlist); } finally: @@ -392,33 +428,37 @@ ushort_converter(PyObject *obj, void *ptr) return 1; } -PyDoc_STRVAR(poll_register_doc, -"register(fd [, eventmask] ) -> None\n\n\ -Register a file descriptor with the polling object.\n\ -fd -- either an integer, or an object with a fileno() method returning an\n\ - int.\n\ -events -- an optional bitmask describing the type of events to check for"); +/*[clinic input] +select.poll.register + + fd: object + either an integer, or an object with a fileno() method returning an int + eventmask: object(converter="ushort_converter", type="unsigned short", c_default="POLLIN | POLLPRI | POLLOUT") = select.POLLIN | select.POLLPRI | select.POLLOUT + an optional bitmask describing the type of events to check for + / + +Register a file descriptor with the polling object. +[clinic start generated code]*/ static PyObject * -poll_register(pollObject *self, PyObject *args) +select_poll_register_impl(pollObject *self, PyObject *fd, + unsigned short eventmask) +/*[clinic end generated code: output=9d124fac4c62aa77 input=31fa73ae25f7179d]*/ { - PyObject *o, *key, *value; - int fd; - unsigned short events = POLLIN | POLLPRI | POLLOUT; + PyObject *key, *value; + int real_fd; int err; - if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events)) + real_fd = PyObject_AsFileDescriptor(fd); + if (real_fd == -1) return NULL; - fd = PyObject_AsFileDescriptor(o); - if (fd == -1) return NULL; - /* Add entry to the internal dictionary: the key is the file descriptor, and the value is the event mask. */ - key = PyLong_FromLong(fd); + key = PyLong_FromLong(real_fd); if (key == NULL) return NULL; - value = PyLong_FromLong(events); + value = PyLong_FromLong(eventmask); if (value == NULL) { Py_DECREF(key); return NULL; @@ -434,29 +474,34 @@ poll_register(pollObject *self, PyObject *args) Py_RETURN_NONE; } -PyDoc_STRVAR(poll_modify_doc, -"modify(fd, eventmask) -> None\n\n\ -Modify an already registered file descriptor.\n\ -fd -- either an integer, or an object with a fileno() method returning an\n\ - int.\n\ -events -- an optional bitmask describing the type of events to check for"); + +/*[clinic input] +select.poll.modify + + fd: object + either an integer, or an object with a fileno() method returning + an int + eventmask: object(converter="ushort_converter", type="unsigned short") + an optional bitmask describing the type of events to check for + / + +Modify an already registered file descriptor. +[clinic start generated code]*/ static PyObject * -poll_modify(pollObject *self, PyObject *args) +select_poll_modify_impl(pollObject *self, PyObject *fd, + unsigned short eventmask) +/*[clinic end generated code: output=427cf336fe49a058 input=bdc9f5f28b019060]*/ { - PyObject *o, *key, *value; - int fd; - unsigned short events; + PyObject *key, *value; + int real_fd; int err; - if (!PyArg_ParseTuple(args, "OO&:modify", &o, ushort_converter, &events)) - return NULL; - - fd = PyObject_AsFileDescriptor(o); - if (fd == -1) return NULL; + real_fd = PyObject_AsFileDescriptor(fd); + if (real_fd == -1) return NULL; /* Modify registered fd */ - key = PyLong_FromLong(fd); + key = PyLong_FromLong(real_fd); if (key == NULL) return NULL; if (PyDict_GetItem(self->dict, key) == NULL) { @@ -465,7 +510,7 @@ poll_modify(pollObject *self, PyObject *args) Py_DECREF(key); return NULL; } - value = PyLong_FromLong(events); + value = PyLong_FromLong(eventmask); if (value == NULL) { Py_DECREF(key); return NULL; @@ -482,22 +527,28 @@ poll_modify(pollObject *self, PyObject *args) } -PyDoc_STRVAR(poll_unregister_doc, -"unregister(fd) -> None\n\n\ -Remove a file descriptor being tracked by the polling object."); +/*[clinic input] +select.poll.unregister + + fd: object + / + +Remove a file descriptor being tracked by the polling object. +[clinic start generated code]*/ static PyObject * -poll_unregister(pollObject *self, PyObject *o) +select_poll_unregister(pollObject *self, PyObject *fd) +/*[clinic end generated code: output=63e6c416dfc6885c input=b7aee1686050e355]*/ { PyObject *key; - int fd; + int real_fd; - fd = PyObject_AsFileDescriptor( o ); - if (fd == -1) + real_fd = PyObject_AsFileDescriptor(fd); + if (real_fd == -1) return NULL; /* Check whether the fd is already in the array */ - key = PyLong_FromLong(fd); + key = PyLong_FromLong(real_fd); if (key == NULL) return NULL; @@ -514,15 +565,22 @@ poll_unregister(pollObject *self, PyObject *o) Py_RETURN_NONE; } -PyDoc_STRVAR(poll_poll_doc, -"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\ -Polls the set of registered file descriptors, returning a list containing \n\ -any descriptors that have events or errors to report."); +/*[clinic input] +select.poll.poll + + timeout as timeout_obj: 'O' = None + / + +Polls the set of registered file descriptors, returning a list containing +any descriptors that have events or errors to report, as a list of +(fd, event) 2-tuples. +[clinic start generated code]*/ static PyObject * -poll_poll(pollObject *self, PyObject *args) +select_poll_poll_impl(pollObject *self, PyObject *timeout_obj) +/*[clinic end generated code: output=876e837d193ed7e4 input=441bb3e6d1d77c5e]*/ { - PyObject *result_list = NULL, *timeout_obj = NULL; + PyObject *result_list = NULL; int poll_result, i, j; PyObject *value = NULL, *num = NULL; _PyTime_t timeout = -1, ms = -1, deadline = 0; @@ -662,15 +720,11 @@ poll_poll(pollObject *self, PyObject *args) } static PyMethodDef poll_methods[] = { - {"register", (PyCFunction)poll_register, - METH_VARARGS, poll_register_doc}, - {"modify", (PyCFunction)poll_modify, - METH_VARARGS, poll_modify_doc}, - {"unregister", (PyCFunction)poll_unregister, - METH_O, poll_unregister_doc}, - {"poll", (PyCFunction)poll_poll, - METH_VARARGS, poll_poll_doc}, - {NULL, NULL} /* sentinel */ + SELECT_POLL_REGISTER_METHODDEF + SELECT_POLL_MODIFY_METHODDEF + SELECT_POLL_UNREGISTER_METHODDEF + SELECT_POLL_POLL_METHODDEF + {NULL, NULL} /* sentinel */ }; static pollObject * @@ -892,10 +946,6 @@ devpoll_poll(devpollObject *self, PyObject *args) if (self->fd_devpoll < 0) return devpoll_err_closed(); - if (!PyArg_ParseTuple(args, "|O:poll", &timeout_obj)) { - return NULL; - } - /* Check values for timeout */ if (timeout_obj == NULL || timeout_obj == Py_None) { timeout = -1; @@ -1157,24 +1207,32 @@ static PyTypeObject devpoll_Type = { #endif /* HAVE_SYS_DEVPOLL_H */ +/*[clinic input] +select.poll -PyDoc_STRVAR(poll_doc, -"Returns a polling object, which supports registering and\n\ -unregistering file descriptors, and then polling them for I/O events."); +Returns a polling object, which supports registering and +unregistering file descriptors, and then polling them for I/O events. +[clinic start generated code]*/ static PyObject * -select_poll(PyObject *self, PyObject *unused) +select_poll_impl(PyModuleDef *module) +/*[clinic end generated code: output=dec103b35a571300 input=1c229cd900442316]*/ { return (PyObject *)newPollObject(); } #ifdef HAVE_SYS_DEVPOLL_H -PyDoc_STRVAR(devpoll_doc, -"Returns a polling object, which supports registering and\n\ -unregistering file descriptors, and then polling them for I/O events."); + +/*[clinic input] +select.devpoll + +Returns a polling object, which supports registering and +unregistering file descriptors, and then polling them for I/O events. +[clinic start generated code]*/ static PyObject * -select_devpoll(PyObject *self, PyObject *unused) +select_devpoll_impl(PyModuleDef *module) +/*[clinic end generated code: output=4ae995f88c797e9a input=3c9b5d31501c8bbb]*/ { return (PyObject *)newDevPollObject(); } @@ -1294,15 +1352,23 @@ newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd) } +/*[clinic input] +@classmethod +select.epoll.__new__ as pyepoll_new + + sizehint: int(c_default="FD_SETSIZE - 1") = -1 + sizehint must be a positive integer or -1 for the default size. The + sizehint is used to optimize internal data structures. It doesn't limit + the maximum number of monitored events. + flags: int = 0 + +Returns an epolling object. +[clinic start generated code]*/ + static PyObject * -pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +pyepoll_new_impl(PyTypeObject *type, int sizehint, int flags) +/*[clinic end generated code: output=fcb34fe462324b94 input=393ae68c1e95c8dd]*/ { - int flags = 0, sizehint = FD_SETSIZE - 1; - static char *kwlist[] = {"sizehint", "flags", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:epoll", kwlist, - &sizehint, &flags)) - return NULL; if (sizehint < 0) { PyErr_SetString(PyExc_ValueError, "negative sizehint"); return NULL; @@ -1323,8 +1389,17 @@ pyepoll_dealloc(pyEpoll_Object *self) Py_TYPE(self)->tp_free(self); } -static PyObject* -pyepoll_close(pyEpoll_Object *self) +/*[clinic input] +select.epoll.close as pyepoll_close + +Close the epoll control file descriptor. + +Further operations on the epoll object will raise an exception. +[clinic start generated code]*/ + +static PyObject * +pyepoll_close_impl(pyEpoll_Object *self) +/*[clinic end generated code: output=8a45f35c8a91003f input=8eb5514f13b41be7]*/ { errno = pyepoll_internal_close(self); if (errno < 0) { @@ -1334,11 +1409,6 @@ pyepoll_close(pyEpoll_Object *self) Py_RETURN_NONE; } -PyDoc_STRVAR(pyepoll_close_doc, -"close() -> None\n\ -\n\ -Close the epoll control file descriptor. Further operations on the epoll\n\ -object will raise an exception."); static PyObject* pyepoll_get_closed(pyEpoll_Object *self) @@ -1349,34 +1419,40 @@ pyepoll_get_closed(pyEpoll_Object *self) Py_RETURN_FALSE; } -static PyObject* -pyepoll_fileno(pyEpoll_Object *self) +/*[clinic input] +select.epoll.fileno as pyepoll_fileno + +Return the epoll control file descriptor. +[clinic start generated code]*/ + +static PyObject * +pyepoll_fileno_impl(pyEpoll_Object *self) +/*[clinic end generated code: output=fe410e728fb9d923 input=f57a7ce98e39b879]*/ { if (self->epfd < 0) return pyepoll_err_closed(); return PyLong_FromLong(self->epfd); } -PyDoc_STRVAR(pyepoll_fileno_doc, -"fileno() -> int\n\ -\n\ -Return the epoll control file descriptor."); -static PyObject* -pyepoll_fromfd(PyObject *cls, PyObject *args) -{ - SOCKET fd; +/*[clinic input] +@classmethod +select.epoll.fromfd as pyepoll_fromfd - if (!PyArg_ParseTuple(args, "i:fromfd", &fd)) - return NULL; + fd: 'i' + / - return newPyEpoll_Object((PyTypeObject*)cls, FD_SETSIZE - 1, fd); +Create an epoll object from a given control fd. +[clinic start generated code]*/ + +static PyObject * +pyepoll_fromfd_impl(PyTypeObject *type, int fd) +/*[clinic end generated code: output=d1efabee2ab54d69 input=358e846d16858997]*/ +{ + SOCKET s_fd = (SOCKET)fd; + return newPyEpoll_Object(type, FD_SETSIZE - 1, 0, s_fd); } -PyDoc_STRVAR(pyepoll_fromfd_doc, -"fromfd(fd) -> epoll\n\ -\n\ -Create an epoll object from a given control fd."); static PyObject * pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events) @@ -1427,77 +1503,80 @@ pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events) Py_RETURN_NONE; } -static PyObject * -pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds) -{ - PyObject *pfd; - unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI; - static char *kwlist[] = {"fd", "eventmask", NULL}; +/*[clinic input] +select.epoll.register as pyepoll_register - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist, - &pfd, &events)) { - return NULL; - } + fd: object + the target file descriptor of the operation + eventmask: unsigned_int(c_default="EPOLLIN | EPOLLOUT | EPOLLPRI", bitwise=True) = EPOLLIN | EPOLLOUT | EPOLLPRI + a bit set composed of the various EPOLL constants - return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events); -} +Registers a new fd or raises an OSError if the fd is already registered. -PyDoc_STRVAR(pyepoll_register_doc, -"register(fd[, eventmask]) -> None\n\ -\n\ -Registers a new fd or raises an OSError if the fd is already registered.\n\ -fd is the target file descriptor of the operation.\n\ -events is a bit set composed of the various EPOLL constants; the default\n\ -is EPOLLIN | EPOLLOUT | EPOLLPRI.\n\ -\n\ -The epoll interface supports all file descriptors that support poll."); +The epoll interface supports all file descriptors that support poll. +[clinic start generated code]*/ static PyObject * -pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds) +pyepoll_register_impl(pyEpoll_Object *self, PyObject *fd, + unsigned int eventmask) +/*[clinic end generated code: output=7c03082c701b4386 input=c99c02f898fd1f94]*/ { - PyObject *pfd; - unsigned int events; - static char *kwlist[] = {"fd", "eventmask", NULL}; + return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, fd, eventmask); +} - if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist, - &pfd, &events)) { - return NULL; - } +/*[clinic input] +select.epoll.modify as pyepoll_modify - return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events); + fd: object + the target file descriptor of the operation + eventmask: unsigned_int(bitwise=True) + a bit set composed of the various EPOLL constants + +Modify event mask for a registered file descriptor. +[clinic start generated code]*/ +static PyObject * +pyepoll_modify_impl(pyEpoll_Object *self, PyObject *fd, + unsigned int eventmask) +/*[clinic end generated code: output=3d18cbb713866267 input=e886ded6eaf213f2]*/ +{ + return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, fd, eventmask); } -PyDoc_STRVAR(pyepoll_modify_doc, -"modify(fd, eventmask) -> None\n\ -\n\ -fd is the target file descriptor of the operation\n\ -events is a bit set composed of the various EPOLL constants"); +/*[clinic input] +select.epoll.unregister as pyepoll_unregister + + fd: object + the target file descriptor of the operation + +Remove a registered file descriptor from the epoll object. +[clinic start generated code]*/ static PyObject * -pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds) +pyepoll_unregister_impl(pyEpoll_Object *self, PyObject *fd) +/*[clinic end generated code: output=83dac1817f807c2d input=c07c186cdc5e721f]*/ { - PyObject *pfd; - static char *kwlist[] = {"fd", NULL}; + return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, fd, 0); +} - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist, - &pfd)) { - return NULL; - } +/*[clinic input] +select.epoll.poll as pyepoll_poll - return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0); -} + timeout as timeout_obj: object(c_default="Py_None") = -1.0 + maxevents: int = -1 -PyDoc_STRVAR(pyepoll_unregister_doc, -"unregister(fd) -> None\n\ -\n\ -fd is the target file descriptor of the operation."); +Wait for events on the epoll file descriptor. + +timeout gives the maximum time to wait in seconds (as float). +A timeout of -1 makes poll wait indefinitely. +Up to maxevents are returned to the caller. + +The return value is a list of tuples of the form (fd, events). +[clinic start generated code]*/ static PyObject * -pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds) +pyepoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj, int maxevents) +/*[clinic end generated code: output=f2d43090f6f8c981 input=487e7c8511237fda]*/ { - static char *kwlist[] = {"timeout", "maxevents", NULL}; - PyObject *timeout_obj = NULL; - int maxevents = -1; int nfds, i; PyObject *elist = NULL, *etuple = NULL; struct epoll_event *evs = NULL; @@ -1506,12 +1585,7 @@ pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds) if (self->epfd < 0) return pyepoll_err_closed(); - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:poll", kwlist, - &timeout_obj, &maxevents)) { - return NULL; - } - - if (timeout_obj == NULL || timeout_obj == Py_None) { + if (timeout_obj == Py_None) { timeout = -1; ms = -1; deadline = 0; /* initialize to prevent gcc warning */ @@ -1601,15 +1675,15 @@ pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds) return elist; } -PyDoc_STRVAR(pyepoll_poll_doc, -"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\ -\n\ -Wait for events on the epoll file descriptor for a maximum time of timeout\n\ -in seconds (as float). -1 makes poll wait indefinitely.\n\ -Up to maxevents are returned to the caller."); + +/*[clinic input] +select.epoll.__enter__ as pyepoll_enter + +[clinic start generated code]*/ static PyObject * -pyepoll_enter(pyEpoll_Object *self, PyObject *args) +pyepoll_enter_impl(pyEpoll_Object *self) +/*[clinic end generated code: output=b83429abc001fbad input=10e21534771c340a]*/ { if (self->epfd < 0) return pyepoll_err_closed(); @@ -1618,33 +1692,36 @@ pyepoll_enter(pyEpoll_Object *self, PyObject *args) return (PyObject *)self; } +/*[clinic input] +select.epoll.__exit__ as pyepoll_exit + + exc_type: object = None + exc_value: object = None + exc_tb: object = None + / + +[clinic start generated code]*/ + static PyObject * -pyepoll_exit(PyObject *self, PyObject *args) +pyepoll_exit_impl(pyEpoll_Object *self, PyObject *exc_type, + PyObject *exc_value, PyObject *exc_tb) +/*[clinic end generated code: output=2a9663282b522719 input=b9e36359f35eadb4]*/ { _Py_IDENTIFIER(close); - return _PyObject_CallMethodId(self, &PyId_close, NULL); + return _PyObject_CallMethodId((PyObject *)self, &PyId_close, NULL); } static PyMethodDef pyepoll_methods[] = { - {"fromfd", (PyCFunction)pyepoll_fromfd, - METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc}, - {"close", (PyCFunction)pyepoll_close, METH_NOARGS, - pyepoll_close_doc}, - {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS, - pyepoll_fileno_doc}, - {"modify", (PyCFunction)pyepoll_modify, - METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc}, - {"register", (PyCFunction)pyepoll_register, - METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc}, - {"unregister", (PyCFunction)pyepoll_unregister, - METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc}, - {"poll", (PyCFunction)pyepoll_poll, - METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc}, - {"__enter__", (PyCFunction)pyepoll_enter, METH_NOARGS, - NULL}, - {"__exit__", (PyCFunction)pyepoll_exit, METH_VARARGS, - NULL}, + SELECT_EPOLL_FROMFD_METHODDEF + SELECT_EPOLL_CLOSE_METHODDEF + SELECT_EPOLL_FILENO_METHODDEF + SELECT_EPOLL_MODIFY_METHODDEF + SELECT_EPOLL_REGISTER_METHODDEF + SELECT_EPOLL_UNREGISTER_METHODDEF + SELECT_EPOLL_POLL_METHODDEF + SELECT_EPOLL___ENTER___METHODDEF + SELECT_EPOLL___EXIT___METHODDEF {NULL, NULL}, }; @@ -1654,14 +1731,6 @@ static PyGetSetDef pyepoll_getsetlist[] = { {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."); static PyTypeObject pyEpoll_Type = { PyVarObject_HEAD_INIT(NULL, 0) @@ -1684,7 +1753,7 @@ static PyTypeObject pyEpoll_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ - pyepoll_doc, /* tp_doc */ + select_epoll__doc__, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ @@ -1701,7 +1770,7 @@ static PyTypeObject pyEpoll_Type = { 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - pyepoll_new, /* tp_new */ + select_epoll, /* tp_new */ 0, /* tp_free */ }; @@ -2353,38 +2422,11 @@ static PyTypeObject kqueue_queue_Type = { /* ************************************************************************ */ -PyDoc_STRVAR(select_doc, -"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\ -\n\ -Wait until one or more file descriptors are ready for some kind of I/O.\n\ -The first three arguments are sequences of file descriptors to be waited for:\n\ -rlist -- wait until ready for reading\n\ -wlist -- wait until ready for writing\n\ -xlist -- wait for an ``exceptional condition''\n\ -If only one kind of condition is required, pass [] for the other lists.\n\ -A file descriptor is either a socket or file object, or a small integer\n\ -gotten from a fileno() method call on one of those.\n\ -\n\ -The optional 4th argument specifies a timeout in seconds; it may be\n\ -a floating point number to specify fractions of seconds. If it is absent\n\ -or None, the call will never time out.\n\ -\n\ -The return value is a tuple of three lists corresponding to the first three\n\ -arguments; each contains the subset of the corresponding file descriptors\n\ -that are ready.\n\ -\n\ -*** IMPORTANT NOTICE ***\n\ -On Windows, only sockets are supported; on Unix, all file\n\ -descriptors can be used."); static PyMethodDef select_methods[] = { - {"select", select_select, METH_VARARGS, select_doc}, -#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL) - {"poll", select_poll, METH_NOARGS, poll_doc}, -#endif /* HAVE_POLL */ -#ifdef HAVE_SYS_DEVPOLL_H - {"devpoll", select_devpoll, METH_NOARGS, devpoll_doc}, -#endif + SELECT_SELECT_METHODDEF + SELECT_POLL_METHODDEF + SELECT_DEVPOLL_METHODDEF {0, 0}, /* sentinel */ }; From 3423836860926c4ad22c25945f7d8a8c9e193a08 Mon Sep 17 00:00:00 2001 From: Tal Einat Date: Tue, 31 Oct 2017 12:07:21 +0200 Subject: [PATCH 02/17] bpo-20182: AC convert new select.kqueue and fix missing summary lines --- Modules/clinic/selectmodule.c.h | 338 +++++++++++++++++++++++++------- Modules/selectmodule.c | 234 +++++++++++----------- 2 files changed, 383 insertions(+), 189 deletions(-) diff --git a/Modules/clinic/selectmodule.c.h b/Modules/clinic/selectmodule.c.h index 80208ef972d547..7165755d314f89 100644 --- a/Modules/clinic/selectmodule.c.h +++ b/Modules/clinic/selectmodule.c.h @@ -9,9 +9,9 @@ PyDoc_STRVAR(select_select__doc__, "Wait until one or more file descriptors are ready for some kind of I/O.\n" "\n" "The first three arguments are sequences of file descriptors to be waited for:\n" -" rlist -- wait until ready for reading\n" -" wlist -- wait until ready for writing\n" -" xlist -- wait for an ``exceptional condition\'\'\n" +"rlist -- wait until ready for reading\n" +"wlist -- wait until ready for writing\n" +"xlist -- wait for an ``exceptional condition\'\'\n" "If only one kind of condition is required, pass [] for the other lists.\n" "A file descriptor is either a socket or file object, or a small integer\n" "gotten from a fileno() method call on one of those.\n" @@ -25,18 +25,18 @@ PyDoc_STRVAR(select_select__doc__, "that are ready.\n" "\n" "*** IMPORTANT NOTICE ***\n" -"On Windows only sockets are supported; on Unix, all file descriptors\n" -"can be used."); +"On Windows, only sockets are supported; on Unix, all file\n" +"descriptors can be used."); #define SELECT_SELECT_METHODDEF \ - {"select", (PyCFunction)select_select, METH_VARARGS, select_select__doc__}, + {"select", (PyCFunction)select_select, METH_FASTCALL, select_select__doc__}, static PyObject * -select_select_impl(PyModuleDef *module, PyObject *rlist, PyObject *wlist, +select_select_impl(PyObject *module, PyObject *rlist, PyObject *wlist, PyObject *xlist, PyObject *timeout_obj); static PyObject * -select_select(PyModuleDef *module, PyObject *args) +select_select(PyObject *module, PyObject **args, Py_ssize_t nargs) { PyObject *return_value = NULL; PyObject *rlist; @@ -44,10 +44,11 @@ select_select(PyModuleDef *module, PyObject *args) PyObject *xlist; PyObject *timeout_obj = Py_None; - if (!PyArg_UnpackTuple(args, "select", + if (!_PyArg_UnpackStack(args, nargs, "select", 3, 4, - &rlist, &wlist, &xlist, &timeout_obj)) + &rlist, &wlist, &xlist, &timeout_obj)) { goto exit; + } return_value = select_select_impl(module, rlist, wlist, xlist, timeout_obj); exit: @@ -64,28 +65,28 @@ PyDoc_STRVAR(select_poll_register__doc__, "Register a file descriptor with the polling object.\n" "\n" " fd\n" -" either an integer, or an object with a fileno() method returning\n" -" an int\n" +" either an integer, or an object with a fileno() method returning an int\n" " eventmask\n" " an optional bitmask describing the type of events to check for"); #define SELECT_POLL_REGISTER_METHODDEF \ - {"register", (PyCFunction)select_poll_register, METH_VARARGS, select_poll_register__doc__}, + {"register", (PyCFunction)select_poll_register, METH_FASTCALL, select_poll_register__doc__}, static PyObject * select_poll_register_impl(pollObject *self, PyObject *fd, unsigned short eventmask); static PyObject * -select_poll_register(pollObject *self, PyObject *args) +select_poll_register(pollObject *self, PyObject **args, Py_ssize_t nargs) { PyObject *return_value = NULL; PyObject *fd; unsigned short eventmask = POLLIN | POLLPRI | POLLOUT; - if (!PyArg_ParseTuple(args, "O|O&:register", - &fd, ushort_converter, &eventmask)) + if (!_PyArg_ParseStack(args, nargs, "O|O&:register", + &fd, ushort_converter, &eventmask)) { goto exit; + } return_value = select_poll_register_impl(self, fd, eventmask); exit: @@ -109,22 +110,23 @@ PyDoc_STRVAR(select_poll_modify__doc__, " an optional bitmask describing the type of events to check for"); #define SELECT_POLL_MODIFY_METHODDEF \ - {"modify", (PyCFunction)select_poll_modify, METH_VARARGS, select_poll_modify__doc__}, + {"modify", (PyCFunction)select_poll_modify, METH_FASTCALL, select_poll_modify__doc__}, static PyObject * select_poll_modify_impl(pollObject *self, PyObject *fd, unsigned short eventmask); static PyObject * -select_poll_modify(pollObject *self, PyObject *args) +select_poll_modify(pollObject *self, PyObject **args, Py_ssize_t nargs) { PyObject *return_value = NULL; PyObject *fd; unsigned short eventmask; - if (!PyArg_ParseTuple(args, "OO&:modify", - &fd, ushort_converter, &eventmask)) + if (!_PyArg_ParseStack(args, nargs, "OO&:modify", + &fd, ushort_converter, &eventmask)) { goto exit; + } return_value = select_poll_modify_impl(self, fd, eventmask); exit: @@ -154,25 +156,26 @@ PyDoc_STRVAR(select_poll_poll__doc__, "\n" "Polls the set of registered file descriptors.\n" "\n" -"Return value is a list containing any descriptors that have events\n" -"or errors to report, in the form of tuples (fd, event)."); +"Returns a list containing any descriptors that have events or errors to report,\n" +"as a list of (fd, event) 2-tuples."); #define SELECT_POLL_POLL_METHODDEF \ - {"poll", (PyCFunction)select_poll_poll, METH_VARARGS, select_poll_poll__doc__}, + {"poll", (PyCFunction)select_poll_poll, METH_FASTCALL, select_poll_poll__doc__}, static PyObject * select_poll_poll_impl(pollObject *self, PyObject *timeout_obj); static PyObject * -select_poll_poll(pollObject *self, PyObject *args) +select_poll_poll(pollObject *self, PyObject **args, Py_ssize_t nargs) { PyObject *return_value = NULL; PyObject *timeout_obj = Py_None; - if (!PyArg_UnpackTuple(args, "poll", + if (!_PyArg_UnpackStack(args, nargs, "poll", 0, 1, - &timeout_obj)) + &timeout_obj)) { goto exit; + } return_value = select_poll_poll_impl(self, timeout_obj); exit: @@ -189,17 +192,17 @@ PyDoc_STRVAR(select_poll__doc__, "\n" "Returns a polling object.\n" "\n" -"The object supports registering and unregistering file descriptors,\n" -"and then polling them for I/O events."); +"This object supports registering and unregistering file descriptors, and then\n" +"polling them for I/O events."); #define SELECT_POLL_METHODDEF \ {"poll", (PyCFunction)select_poll, METH_NOARGS, select_poll__doc__}, static PyObject * -select_poll_impl(PyModuleDef *module); +select_poll_impl(PyObject *module); static PyObject * -select_poll(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +select_poll(PyObject *module, PyObject *Py_UNUSED(ignored)) { return select_poll_impl(module); } @@ -212,19 +215,19 @@ PyDoc_STRVAR(select_devpoll__doc__, "devpoll($module, /)\n" "--\n" "\n" -"Returns a polling object using /dev/poll.\n" +"Returns a polling object.\n" "\n" -"The object supports registering and unregistering file descriptors,\n" -"and then polling them for I/O events."); +"This object supports registering and unregistering file descriptors, and then\n" +"polling them for I/O events."); #define SELECT_DEVPOLL_METHODDEF \ {"devpoll", (PyCFunction)select_devpoll, METH_NOARGS, select_devpoll__doc__}, static PyObject * -select_devpoll_impl(PyModuleDef *module); +select_devpoll_impl(PyObject *module); static PyObject * -select_devpoll(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +select_devpoll(PyObject *module, PyObject *Py_UNUSED(ignored)) { return select_devpoll_impl(module); } @@ -239,9 +242,10 @@ PyDoc_STRVAR(pyepoll_new__doc__, "\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."); +" sizehint\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."); static PyObject * pyepoll_new_impl(PyTypeObject *type, int sizehint, int flags); @@ -250,13 +254,15 @@ static PyObject * pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"sizehint", "flags", NULL}; + static const char * const _keywords[] = {"sizehint", "flags", NULL}; + static _PyArg_Parser _parser = {"|ii:epoll", _keywords, 0}; int sizehint = FD_SETSIZE - 1; int flags = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii:epoll", _keywords, - &sizehint, &flags)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &sizehint, &flags)) { goto exit; + } return_value = pyepoll_new_impl(type, sizehint, flags); exit: @@ -331,8 +337,9 @@ pyepoll_fromfd(PyTypeObject *type, PyObject *arg) PyObject *return_value = NULL; int fd; - if (!PyArg_Parse(arg, "i:fromfd", &fd)) + if (!PyArg_Parse(arg, "i:fromfd", &fd)) { goto exit; + } return_value = pyepoll_fromfd_impl(type, fd); exit: @@ -344,36 +351,38 @@ pyepoll_fromfd(PyTypeObject *type, PyObject *arg) #if defined(HAVE_EPOLL) PyDoc_STRVAR(pyepoll_register__doc__, -"register($self, /, fd,\n" -" eventmask=select.EPOLLIN | select.EPOLLOUT | select.EPOLLPRI)\n" +"register($self, /, fd, eventmask=EPOLLIN | EPOLLOUT | EPOLLPRI)\n" "--\n" "\n" "Registers a new fd or raises an OSError if the fd is already registered.\n" "\n" -"fd is the target file descriptor of the operation.\n" -"events is a bit set composed of the various EPOLL constants; the default\n" -"is EPOLLIN | EPOLLOUT | EPOLLPRI.\n" +" fd\n" +" the target file descriptor of the operation\n" +" eventmask\n" +" a bit set composed of the various EPOLL constants\n" "\n" "The epoll interface supports all file descriptors that support poll."); #define PYEPOLL_REGISTER_METHODDEF \ - {"register", (PyCFunction)pyepoll_register, METH_VARARGS|METH_KEYWORDS, pyepoll_register__doc__}, + {"register", (PyCFunction)pyepoll_register, METH_FASTCALL|METH_KEYWORDS, pyepoll_register__doc__}, static PyObject * pyepoll_register_impl(pyEpoll_Object *self, PyObject *fd, unsigned int eventmask); static PyObject * -pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwargs) +pyepoll_register(pyEpoll_Object *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - static char *_keywords[] = {"fd", "eventmask", NULL}; + static const char * const _keywords[] = {"fd", "eventmask", NULL}; + static _PyArg_Parser _parser = {"O|I:register", _keywords, 0}; PyObject *fd; unsigned int eventmask = EPOLLIN | EPOLLOUT | EPOLLPRI; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|I:register", _keywords, - &fd, &eventmask)) + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &fd, &eventmask)) { goto exit; + } return_value = pyepoll_register_impl(self, fd, eventmask); exit: @@ -390,27 +399,31 @@ PyDoc_STRVAR(pyepoll_modify__doc__, "\n" "Modify event mask for a registered file descriptor.\n" "\n" -"fd is the target file descriptor of the operation, and\n" -"events is a bit set composed of the various EPOLL constants."); +" fd\n" +" the target file descriptor of the operation\n" +" eventmask\n" +" a bit set composed of the various EPOLL constants"); #define PYEPOLL_MODIFY_METHODDEF \ - {"modify", (PyCFunction)pyepoll_modify, METH_VARARGS|METH_KEYWORDS, pyepoll_modify__doc__}, + {"modify", (PyCFunction)pyepoll_modify, METH_FASTCALL|METH_KEYWORDS, pyepoll_modify__doc__}, static PyObject * pyepoll_modify_impl(pyEpoll_Object *self, PyObject *fd, unsigned int eventmask); static PyObject * -pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwargs) +pyepoll_modify(pyEpoll_Object *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - static char *_keywords[] = {"fd", "eventmask", NULL}; + static const char * const _keywords[] = {"fd", "eventmask", NULL}; + static _PyArg_Parser _parser = {"OI:modify", _keywords, 0}; PyObject *fd; unsigned int eventmask; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OI:modify", _keywords, - &fd, &eventmask)) + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &fd, &eventmask)) { goto exit; + } return_value = pyepoll_modify_impl(self, fd, eventmask); exit: @@ -427,24 +440,27 @@ PyDoc_STRVAR(pyepoll_unregister__doc__, "\n" "Remove a registered file descriptor from the epoll object.\n" "\n" -"fd is the target file descriptor of the operation."); +" fd\n" +" the target file descriptor of the operation"); #define PYEPOLL_UNREGISTER_METHODDEF \ - {"unregister", (PyCFunction)pyepoll_unregister, METH_VARARGS|METH_KEYWORDS, pyepoll_unregister__doc__}, + {"unregister", (PyCFunction)pyepoll_unregister, METH_FASTCALL|METH_KEYWORDS, pyepoll_unregister__doc__}, static PyObject * pyepoll_unregister_impl(pyEpoll_Object *self, PyObject *fd); static PyObject * -pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwargs) +pyepoll_unregister(pyEpoll_Object *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - static char *_keywords[] = {"fd", NULL}; + static const char * const _keywords[] = {"fd", NULL}; + static _PyArg_Parser _parser = {"O:unregister", _keywords, 0}; PyObject *fd; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:unregister", _keywords, - &fd)) + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &fd)) { goto exit; + } return_value = pyepoll_unregister_impl(self, fd); exit: @@ -468,22 +484,24 @@ PyDoc_STRVAR(pyepoll_poll__doc__, "The return value is a list of tuples of the form (fd, events)."); #define PYEPOLL_POLL_METHODDEF \ - {"poll", (PyCFunction)pyepoll_poll, METH_VARARGS|METH_KEYWORDS, pyepoll_poll__doc__}, + {"poll", (PyCFunction)pyepoll_poll, METH_FASTCALL|METH_KEYWORDS, pyepoll_poll__doc__}, static PyObject * pyepoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj, int maxevents); static PyObject * -pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwargs) +pyepoll_poll(pyEpoll_Object *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - static char *_keywords[] = {"timeout", "maxevents", NULL}; + static const char * const _keywords[] = {"timeout", "maxevents", NULL}; + static _PyArg_Parser _parser = {"|Oi:poll", _keywords, 0}; PyObject *timeout_obj = Py_None; int maxevents = -1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:poll", _keywords, - &timeout_obj, &maxevents)) + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &timeout_obj, &maxevents)) { goto exit; + } return_value = pyepoll_poll_impl(self, timeout_obj, maxevents); exit: @@ -521,24 +539,25 @@ PyDoc_STRVAR(pyepoll_exit__doc__, "\n"); #define PYEPOLL_EXIT_METHODDEF \ - {"__exit__", (PyCFunction)pyepoll_exit, METH_VARARGS, pyepoll_exit__doc__}, + {"__exit__", (PyCFunction)pyepoll_exit, METH_FASTCALL, pyepoll_exit__doc__}, static PyObject * pyepoll_exit_impl(pyEpoll_Object *self, PyObject *exc_type, PyObject *exc_value, PyObject *exc_tb); static PyObject * -pyepoll_exit(pyEpoll_Object *self, PyObject *args) +pyepoll_exit(pyEpoll_Object *self, PyObject **args, Py_ssize_t nargs) { PyObject *return_value = NULL; PyObject *exc_type = Py_None; PyObject *exc_value = Py_None; PyObject *exc_tb = Py_None; - if (!PyArg_UnpackTuple(args, "__exit__", + if (!_PyArg_UnpackStack(args, nargs, "__exit__", 0, 3, - &exc_type, &exc_value, &exc_tb)) + &exc_type, &exc_value, &exc_tb)) { goto exit; + } return_value = pyepoll_exit_impl(self, exc_type, exc_value, exc_tb); exit: @@ -547,6 +566,171 @@ pyepoll_exit(pyEpoll_Object *self, PyObject *args) #endif /* defined(HAVE_EPOLL) */ +#if defined(HAVE_KQUEUE) + +PyDoc_STRVAR(select_kqueue__doc__, +"kqueue()\n" +"--\n" +"\n" +"Kqueue syscall wrapper.\n" +"\n" +"For example, to start watching a socket for input:\n" +">>> kq = kqueue()\n" +">>> sock = socket()\n" +">>> sock.connect((host, port))\n" +">>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n" +"\n" +"To wait one second for it to become writeable:\n" +">>> kq.control(None, 1, 1000)\n" +"\n" +"To stop listening:\n" +">>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)"); + +static PyObject * +select_kqueue_impl(PyTypeObject *type); + +static PyObject * +select_kqueue(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + + if ((type == &kqueue_queue_Type) && + !_PyArg_NoPositional("kqueue", args)) { + goto exit; + } + if ((type == &kqueue_queue_Type) && + !_PyArg_NoKeywords("kqueue", kwargs)) { + goto exit; + } + return_value = select_kqueue_impl(type); + +exit: + return return_value; +} + +#endif /* defined(HAVE_KQUEUE) */ + +#if defined(HAVE_KQUEUE) + +PyDoc_STRVAR(select_kqueue_close__doc__, +"close($self, /)\n" +"--\n" +"\n" +"Close the kqueue control file descriptor.\n" +"\n" +"Further operations on the kqueue object will raise an exception."); + +#define SELECT_KQUEUE_CLOSE_METHODDEF \ + {"close", (PyCFunction)select_kqueue_close, METH_NOARGS, select_kqueue_close__doc__}, + +static PyObject * +select_kqueue_close_impl(kqueue_queue_Object *self); + +static PyObject * +select_kqueue_close(kqueue_queue_Object *self, PyObject *Py_UNUSED(ignored)) +{ + return select_kqueue_close_impl(self); +} + +#endif /* defined(HAVE_KQUEUE) */ + +#if defined(HAVE_KQUEUE) + +PyDoc_STRVAR(select_kqueue_fileno__doc__, +"fileno($self, /)\n" +"--\n" +"\n" +"Return the kqueue control file descriptor."); + +#define SELECT_KQUEUE_FILENO_METHODDEF \ + {"fileno", (PyCFunction)select_kqueue_fileno, METH_NOARGS, select_kqueue_fileno__doc__}, + +static PyObject * +select_kqueue_fileno_impl(kqueue_queue_Object *self); + +static PyObject * +select_kqueue_fileno(kqueue_queue_Object *self, PyObject *Py_UNUSED(ignored)) +{ + return select_kqueue_fileno_impl(self); +} + +#endif /* defined(HAVE_KQUEUE) */ + +#if defined(HAVE_KQUEUE) + +PyDoc_STRVAR(select_kqueue_fromfd__doc__, +"fromfd($type, fd, /)\n" +"--\n" +"\n" +"Create a kqueue object from a given control fd."); + +#define SELECT_KQUEUE_FROMFD_METHODDEF \ + {"fromfd", (PyCFunction)select_kqueue_fromfd, METH_O|METH_CLASS, select_kqueue_fromfd__doc__}, + +static PyObject * +select_kqueue_fromfd_impl(PyTypeObject *type, int fd); + +static PyObject * +select_kqueue_fromfd(PyTypeObject *type, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + + if (!PyArg_Parse(arg, "i:fromfd", &fd)) { + goto exit; + } + return_value = select_kqueue_fromfd_impl(type, fd); + +exit: + return return_value; +} + +#endif /* defined(HAVE_KQUEUE) */ + +#if defined(HAVE_KQUEUE) + +PyDoc_STRVAR(select_kqueue_control__doc__, +"control($self, changelist, maxevents, timeout=None, /)\n" +"--\n" +"\n" +"Calls the kernel kevent function.\n" +"\n" +" changelist\n" +" Must be an iterable of kevent objects describing the changes to be made\n" +" to the kernel\'s watch list or None.\n" +" maxevents\n" +" The maximum number of events that the kernel will return.\n" +" timeout\n" +" The maximum time to wait in seconds, or else None to wait forever.\n" +" This accepts floats for smaller timeouts, too."); + +#define SELECT_KQUEUE_CONTROL_METHODDEF \ + {"control", (PyCFunction)select_kqueue_control, METH_FASTCALL, select_kqueue_control__doc__}, + +static PyObject * +select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist, + int maxevents, PyObject *otimeout); + +static PyObject * +select_kqueue_control(kqueue_queue_Object *self, PyObject **args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *changelist; + int maxevents; + PyObject *otimeout = Py_None; + + if (!_PyArg_ParseStack(args, nargs, "Oi|O:control", + &changelist, &maxevents, &otimeout)) { + goto exit; + } + return_value = select_kqueue_control_impl(self, changelist, maxevents, otimeout); + +exit: + return return_value; +} + +#endif /* defined(HAVE_KQUEUE) */ + #ifndef SELECT_POLL_REGISTER_METHODDEF #define SELECT_POLL_REGISTER_METHODDEF #endif /* !defined(SELECT_POLL_REGISTER_METHODDEF) */ @@ -586,4 +770,8 @@ pyepoll_exit(pyEpoll_Object *self, PyObject *args) #ifndef PYEPOLL_EXIT_METHODDEF #define PYEPOLL_EXIT_METHODDEF #endif /* !defined(PYEPOLL_EXIT_METHODDEF) */ -/*[clinic end generated code: output=8c67fe108dc8d539 input=a9049054013a1b77]*/ + +#ifndef SELECT_KQUEUE_CONTROL_METHODDEF + #define SELECT_KQUEUE_CONTROL_METHODDEF +#endif /* !defined(SELECT_KQUEUE_CONTROL_METHODDEF) */ +/*[clinic end generated code: output=9b828bf16401e09e input=a9049054013a1b77]*/ diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index a41c25972862e4..ccfceff3d2ec8d 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -64,8 +64,9 @@ extern void bzero(void *, int); module select class select.poll "pollObject *" "&poll_Type" class select.epoll "pyEpoll_Object *" "&pyEpoll_Type" +class select.kqueue "kqueue_queue_Object *" "&kqueue_queue_Type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e04c459c99679db4]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ec163a60f69bbb6e]*/ /* list of Python objects and their file descriptor */ @@ -199,6 +200,7 @@ select.select / Wait until one or more file descriptors are ready for some kind of I/O. + The first three arguments are sequences of file descriptors to be waited for: rlist -- wait until ready for reading wlist -- wait until ready for writing @@ -221,9 +223,9 @@ descriptors can be used. [clinic start generated code]*/ static PyObject * -select_select_impl(PyModuleDef *module, PyObject *rlist, PyObject *wlist, +select_select_impl(PyObject *module, PyObject *rlist, PyObject *wlist, PyObject *xlist, PyObject *timeout_obj) -/*[clinic end generated code: output=7f9b92129e855343 input=7dc8f84d5d187916]*/ +/*[clinic end generated code: output=2b3cfa824f7ae4cf input=c001a7f0663e3865]*/ { #ifdef SELECT_USES_HEAP pylist *rfd2obj, *wfd2obj, *efd2obj; @@ -443,7 +445,7 @@ Register a file descriptor with the polling object. static PyObject * select_poll_register_impl(pollObject *self, PyObject *fd, unsigned short eventmask) -/*[clinic end generated code: output=9d124fac4c62aa77 input=31fa73ae25f7179d]*/ +/*[clinic end generated code: output=9d124fac4c62aa77 input=1eb1ecb69aab929b]*/ { PyObject *key, *value; int real_fd; @@ -491,7 +493,7 @@ Modify an already registered file descriptor. static PyObject * select_poll_modify_impl(pollObject *self, PyObject *fd, unsigned short eventmask) -/*[clinic end generated code: output=427cf336fe49a058 input=bdc9f5f28b019060]*/ +/*[clinic end generated code: output=427cf336fe49a058 input=981788186a5846ee]*/ { PyObject *key, *value; int real_fd; @@ -538,7 +540,7 @@ Remove a file descriptor being tracked by the polling object. static PyObject * select_poll_unregister(pollObject *self, PyObject *fd) -/*[clinic end generated code: output=63e6c416dfc6885c input=b7aee1686050e355]*/ +/*[clinic end generated code: output=63e6c416dfc6885c input=69b20d179f588435]*/ { PyObject *key; int real_fd; @@ -568,17 +570,18 @@ select_poll_unregister(pollObject *self, PyObject *fd) /*[clinic input] select.poll.poll - timeout as timeout_obj: 'O' = None + timeout as timeout_obj: object = None / -Polls the set of registered file descriptors, returning a list containing -any descriptors that have events or errors to report, as a list of -(fd, event) 2-tuples. +Polls the set of registered file descriptors. + +Returns a list containing any descriptors that have events or errors to report, +as a list of (fd, event) 2-tuples. [clinic start generated code]*/ static PyObject * select_poll_poll_impl(pollObject *self, PyObject *timeout_obj) -/*[clinic end generated code: output=876e837d193ed7e4 input=441bb3e6d1d77c5e]*/ +/*[clinic end generated code: output=876e837d193ed7e4 input=cd2f4f27914cc62f]*/ { PyObject *result_list = NULL; int poll_result, i, j; @@ -586,10 +589,6 @@ select_poll_poll_impl(pollObject *self, PyObject *timeout_obj) _PyTime_t timeout = -1, ms = -1, deadline = 0; int async_err = 0; - if (!PyArg_ParseTuple(args, "|O:poll", &timeout_obj)) { - return NULL; - } - if (timeout_obj != NULL && timeout_obj != Py_None) { if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj, _PyTime_ROUND_TIMEOUT) < 0) { @@ -1210,13 +1209,15 @@ static PyTypeObject devpoll_Type = { /*[clinic input] select.poll -Returns a polling object, which supports registering and -unregistering file descriptors, and then polling them for I/O events. +Returns a polling object. + +This object supports registering and unregistering file descriptors, and then +polling them for I/O events. [clinic start generated code]*/ static PyObject * -select_poll_impl(PyModuleDef *module) -/*[clinic end generated code: output=dec103b35a571300 input=1c229cd900442316]*/ +select_poll_impl(PyObject *module) +/*[clinic end generated code: output=16a665a4e1d228c5 input=3f877909d5696bbf]*/ { return (PyObject *)newPollObject(); } @@ -1226,13 +1227,15 @@ select_poll_impl(PyModuleDef *module) /*[clinic input] select.devpoll -Returns a polling object, which supports registering and -unregistering file descriptors, and then polling them for I/O events. +Returns a polling object. + +This object supports registering and unregistering file descriptors, and then +polling them for I/O events. [clinic start generated code]*/ static PyObject * -select_devpoll_impl(PyModuleDef *module) -/*[clinic end generated code: output=4ae995f88c797e9a input=3c9b5d31501c8bbb]*/ +select_devpoll_impl(PyObject *module) +/*[clinic end generated code: output=ea9213cc87fd9581 input=53a1af94564f00a3]*/ { return (PyObject *)newDevPollObject(); } @@ -1367,7 +1370,7 @@ Returns an epolling object. static PyObject * pyepoll_new_impl(PyTypeObject *type, int sizehint, int flags) -/*[clinic end generated code: output=fcb34fe462324b94 input=393ae68c1e95c8dd]*/ +/*[clinic end generated code: output=fcb34fe462324b94 input=37a75964694b6816]*/ { if (sizehint < 0) { PyErr_SetString(PyExc_ValueError, "negative sizehint"); @@ -1439,7 +1442,7 @@ pyepoll_fileno_impl(pyEpoll_Object *self) @classmethod select.epoll.fromfd as pyepoll_fromfd - fd: 'i' + fd: int / Create an epoll object from a given control fd. @@ -1447,7 +1450,7 @@ Create an epoll object from a given control fd. static PyObject * pyepoll_fromfd_impl(PyTypeObject *type, int fd) -/*[clinic end generated code: output=d1efabee2ab54d69 input=358e846d16858997]*/ +/*[clinic end generated code: output=d1efabee2ab54d69 input=018090223b95d685]*/ { SOCKET s_fd = (SOCKET)fd; return newPyEpoll_Object(type, FD_SETSIZE - 1, 0, s_fd); @@ -1519,7 +1522,7 @@ The epoll interface supports all file descriptors that support poll. static PyObject * pyepoll_register_impl(pyEpoll_Object *self, PyObject *fd, unsigned int eventmask) -/*[clinic end generated code: output=7c03082c701b4386 input=c99c02f898fd1f94]*/ +/*[clinic end generated code: output=7c03082c701b4386 input=7598971f10e2b318]*/ { return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, fd, eventmask); } @@ -1534,10 +1537,11 @@ select.epoll.modify as pyepoll_modify Modify event mask for a registered file descriptor. [clinic start generated code]*/ + static PyObject * pyepoll_modify_impl(pyEpoll_Object *self, PyObject *fd, unsigned int eventmask) -/*[clinic end generated code: output=3d18cbb713866267 input=e886ded6eaf213f2]*/ +/*[clinic end generated code: output=3d18cbb713866267 input=107c7ca76f0af422]*/ { return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, fd, eventmask); } @@ -1553,7 +1557,7 @@ Remove a registered file descriptor from the epoll object. static PyObject * pyepoll_unregister_impl(pyEpoll_Object *self, PyObject *fd) -/*[clinic end generated code: output=83dac1817f807c2d input=c07c186cdc5e721f]*/ +/*[clinic end generated code: output=83dac1817f807c2d input=39795651cc232dec]*/ { return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, fd, 0); } @@ -1575,7 +1579,7 @@ The return value is a list of tuples of the form (fd, events). static PyObject * pyepoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj, int maxevents) -/*[clinic end generated code: output=f2d43090f6f8c981 input=487e7c8511237fda]*/ +/*[clinic end generated code: output=f2d43090f6f8c981 input=6896abf8945c94e6]*/ { int nfds, i; PyObject *elist = NULL, *etuple = NULL; @@ -2098,16 +2102,29 @@ newKqueue_Object(PyTypeObject *type, SOCKET fd) return (PyObject *)self; } +/*[clinic input] +@classmethod +select.kqueue.__new__ + +Kqueue syscall wrapper. + +For example, to start watching a socket for input: +>>> kq = kqueue() +>>> sock = socket() +>>> sock.connect((host, port)) +>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0) + +To wait one second for it to become writeable: +>>> kq.control(None, 1, 1000) + +To stop listening: +>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0) +[clinic start generated code]*/ + static PyObject * -kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +select_kqueue_impl(PyTypeObject *type) +/*[clinic end generated code: output=e0ff89f154d56236 input=cf625e49218366e8]*/ { - if (PyTuple_GET_SIZE(args) || - (kwds != NULL && PyDict_GET_SIZE(kwds))) { - PyErr_SetString(PyExc_ValueError, - "select.kqueue doesn't accept arguments"); - return NULL; - } - return newKqueue_Object(type, -1); } @@ -2118,8 +2135,17 @@ kqueue_queue_dealloc(kqueue_queue_Object *self) Py_TYPE(self)->tp_free(self); } -static PyObject* -kqueue_queue_close(kqueue_queue_Object *self) +/*[clinic input] +select.kqueue.close + +Close the kqueue control file descriptor. + +Further operations on the kqueue object will raise an exception. +[clinic start generated code]*/ + +static PyObject * +select_kqueue_close_impl(kqueue_queue_Object *self) +/*[clinic end generated code: output=d1c7df0b407a4bc1 input=0b12d95430e0634c]*/ { errno = kqueue_queue_internal_close(self); if (errno < 0) { @@ -2129,12 +2155,6 @@ kqueue_queue_close(kqueue_queue_Object *self) Py_RETURN_NONE; } -PyDoc_STRVAR(kqueue_queue_close_doc, -"close() -> None\n\ -\n\ -Close the kqueue control file descriptor. Further operations on the kqueue\n\ -object will raise an exception."); - static PyObject* kqueue_queue_get_closed(kqueue_queue_Object *self) { @@ -2144,44 +2164,64 @@ kqueue_queue_get_closed(kqueue_queue_Object *self) Py_RETURN_FALSE; } -static PyObject* -kqueue_queue_fileno(kqueue_queue_Object *self) +/*[clinic input] +select.kqueue.fileno + +Return the kqueue control file descriptor. +[clinic start generated code]*/ + +static PyObject * +select_kqueue_fileno_impl(kqueue_queue_Object *self) +/*[clinic end generated code: output=716f46112a4f6e5c input=41911c539ca2b0ca]*/ { if (self->kqfd < 0) return kqueue_queue_err_closed(); return PyLong_FromLong(self->kqfd); } -PyDoc_STRVAR(kqueue_queue_fileno_doc, -"fileno() -> int\n\ -\n\ -Return the kqueue control file descriptor."); +/*[clinic input] +@classmethod +select.kqueue.fromfd -static PyObject* -kqueue_queue_fromfd(PyObject *cls, PyObject *args) -{ - SOCKET fd; + fd: int + / - if (!PyArg_ParseTuple(args, "i:fromfd", &fd)) - return NULL; +Create a kqueue object from a given control fd. +[clinic start generated code]*/ + +static PyObject * +select_kqueue_fromfd_impl(PyTypeObject *type, int fd) +/*[clinic end generated code: output=d02c3c7dc538a653 input=f6172a48ca4ecdd0]*/ +{ + SOCKET s_fd = (SOCKET)fd; - return newKqueue_Object((PyTypeObject*)cls, fd); + return newKqueue_Object((PyTypeObject*)cls, s_fd); } -PyDoc_STRVAR(kqueue_queue_fromfd_doc, -"fromfd(fd) -> kqueue\n\ -\n\ -Create a kqueue object from a given control fd."); +/*[clinic input] +select.kqueue.control + + changelist: object + Must be an iterable of kevent objects describing the changes to be made + to the kernel's watch list or None. + maxevents: int + The maximum number of events that the kernel will return. + timeout as otimeout: object = None + The maximum time to wait in seconds, or else None to wait forever. + This accepts floats for smaller timeouts, too. + / + +Calls the kernel kevent function. +[clinic start generated code]*/ static PyObject * -kqueue_queue_control(kqueue_queue_Object *self, PyObject *args) +select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist, + int maxevents, PyObject *otimeout) +/*[clinic end generated code: output=81324ff5130db7ae input=59c4e30811209c47]*/ { - int nevents = 0; int gotevents = 0; int nchanges = 0; int i = 0; - PyObject *otimeout = NULL; - PyObject *ch = NULL; PyObject *seq = NULL, *ei = NULL; PyObject *result = NULL; struct kevent *evl = NULL; @@ -2193,13 +2233,10 @@ kqueue_queue_control(kqueue_queue_Object *self, PyObject *args) if (self->kqfd < 0) return kqueue_queue_err_closed(); - if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout)) - return NULL; - - if (nevents < 0) { + if (maxevents < 0) { PyErr_Format(PyExc_ValueError, "Length of eventlist must be 0 or positive, got %d", - nevents); + maxevents); return NULL; } @@ -2227,8 +2264,8 @@ kqueue_queue_control(kqueue_queue_Object *self, PyObject *args) ptimeoutspec = &timeoutspec; } - if (ch != NULL && ch != Py_None) { - seq = PySequence_Fast(ch, "changelist is not iterable"); + if (changelist != NULL && changelist != Py_None) { + seq = PySequence_Fast(changelist, "changelist is not iterable"); if (seq == NULL) { return NULL; } @@ -2258,8 +2295,8 @@ kqueue_queue_control(kqueue_queue_Object *self, PyObject *args) } /* event list */ - if (nevents) { - evl = PyMem_New(struct kevent, nevents); + if (maxevents) { + evl = PyMem_New(struct kevent, maxevents); if (evl == NULL) { PyErr_NoMemory(); goto error; @@ -2273,7 +2310,7 @@ kqueue_queue_control(kqueue_queue_Object *self, PyObject *args) Py_BEGIN_ALLOW_THREADS errno = 0; gotevents = kevent(self->kqfd, chl, nchanges, - evl, nevents, ptimeoutspec); + evl, maxevents, ptimeoutspec); Py_END_ALLOW_THREADS if (errno != EINTR) @@ -2327,27 +2364,11 @@ kqueue_queue_control(kqueue_queue_Object *self, PyObject *args) return NULL; } -PyDoc_STRVAR(kqueue_queue_control_doc, -"control(changelist, max_events[, timeout=None]) -> eventlist\n\ -\n\ -Calls the kernel kevent function.\n\ -- changelist must be an iterable of kevent objects describing the changes\n\ - to be made to the kernel's watch list or None.\n\ -- max_events lets you specify the maximum number of events that the\n\ - kernel will return.\n\ -- timeout is the maximum time to wait in seconds, or else None,\n\ - to wait forever. timeout accepts floats for smaller timeouts, too."); - - static PyMethodDef kqueue_queue_methods[] = { - {"fromfd", (PyCFunction)kqueue_queue_fromfd, - METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc}, - {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS, - kqueue_queue_close_doc}, - {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS, - kqueue_queue_fileno_doc}, - {"control", (PyCFunction)kqueue_queue_control, - METH_VARARGS , kqueue_queue_control_doc}, + SELECT_KQUEUE_FROMFD_METHODDEF + SELECT_KQUEUE_CLOSE_METHODDEF + SELECT_KQUEUE_FILENO_METHODDEF + SELECT_KQUEUE_CONTROL_METHODDEF {NULL, NULL}, }; @@ -2357,21 +2378,6 @@ static PyGetSetDef kqueue_queue_getsetlist[] = { {0}, }; -PyDoc_STRVAR(kqueue_queue_doc, -"Kqueue syscall wrapper.\n\ -\n\ -For example, to start watching a socket for input:\n\ ->>> kq = kqueue()\n\ ->>> sock = socket()\n\ ->>> sock.connect((host, port))\n\ ->>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\ -\n\ -To wait one second for it to become writeable:\n\ ->>> kq.control(None, 1, 1000)\n\ -\n\ -To stop listening:\n\ ->>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)"); - static PyTypeObject kqueue_queue_Type = { PyVarObject_HEAD_INIT(NULL, 0) "select.kqueue", /* tp_name */ @@ -2393,7 +2399,7 @@ static PyTypeObject kqueue_queue_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ - kqueue_queue_doc, /* tp_doc */ + select_kqueue__doc__, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ @@ -2410,7 +2416,7 @@ static PyTypeObject kqueue_queue_Type = { 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - kqueue_queue_new, /* tp_new */ + select_kqueue_new, /* tp_new */ 0, /* tp_free */ }; From 778d2403a3c2c611365d9ef23b9028910dfc49fe Mon Sep 17 00:00:00 2001 From: Tal Einat Date: Tue, 31 Oct 2017 19:33:54 +0200 Subject: [PATCH 03/17] bpo-20182: selectmodule.c AC: move type and method defintions to bottom This is required to be able to include the generated AC code from clinic/selectmodule.c.h, which must appear before these definitions but after all typedefs and type declarations. --- Modules/selectmodule.c | 418 +++++++++++++++++++++-------------------- 1 file changed, 219 insertions(+), 199 deletions(-) diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index ccfceff3d2ec8d..b48f7cae414708 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -58,8 +58,6 @@ extern void bzero(void *, int); # define SOCKET int #endif -#include "clinic/selectmodule.c.h" - /*[clinic input] module select class select.poll "pollObject *" "&poll_Type" @@ -581,7 +579,7 @@ as a list of (fd, event) 2-tuples. static PyObject * select_poll_poll_impl(pollObject *self, PyObject *timeout_obj) -/*[clinic end generated code: output=876e837d193ed7e4 input=cd2f4f27914cc62f]*/ +/*[clinic end generated code: output=876e837d193ed7e4 input=65e7913e6a7d2754]*/ { PyObject *result_list = NULL; int poll_result, i, j; @@ -718,14 +716,6 @@ select_poll_poll_impl(pollObject *self, PyObject *timeout_obj) return NULL; } -static PyMethodDef poll_methods[] = { - SELECT_POLL_REGISTER_METHODDEF - SELECT_POLL_MODIFY_METHODDEF - SELECT_POLL_UNREGISTER_METHODDEF - SELECT_POLL_POLL_METHODDEF - {NULL, NULL} /* sentinel */ -}; - static pollObject * newPollObject(void) { @@ -755,39 +745,6 @@ poll_dealloc(pollObject *self) PyObject_Del(self); } -static PyTypeObject poll_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.poll", /*tp_name*/ - sizeof(pollObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)poll_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_reserved*/ - 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*/ - poll_methods, /*tp_methods*/ -}; #ifdef HAVE_SYS_DEVPOLL_H typedef struct { @@ -1093,22 +1050,6 @@ PyDoc_STRVAR(devpoll_fileno_doc, \n\ Return the file descriptor."); -static PyMethodDef devpoll_methods[] = { - {"register", (PyCFunction)devpoll_register, - METH_VARARGS, devpoll_register_doc}, - {"modify", (PyCFunction)devpoll_modify, - METH_VARARGS, devpoll_modify_doc}, - {"unregister", (PyCFunction)devpoll_unregister, - METH_O, devpoll_unregister_doc}, - {"poll", (PyCFunction)devpoll_poll, - METH_VARARGS, devpoll_poll_doc}, - {"close", (PyCFunction)devpoll_close, METH_NOARGS, - devpoll_close_doc}, - {"fileno", (PyCFunction)devpoll_fileno, METH_NOARGS, - devpoll_fileno_doc}, - {NULL, NULL} /* sentinel */ -}; - static PyGetSetDef devpoll_getsetlist[] = { {"closed", (getter)devpoll_get_closed, NULL, "True if the devpoll object is closed"}, @@ -1168,41 +1109,6 @@ devpoll_dealloc(devpollObject *self) PyObject_Del(self); } -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_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_reserved*/ - 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 */ @@ -1716,68 +1622,12 @@ pyepoll_exit_impl(pyEpoll_Object *self, PyObject *exc_type, return _PyObject_CallMethodId((PyObject *)self, &PyId_close, NULL); } -static PyMethodDef pyepoll_methods[] = { - SELECT_EPOLL_FROMFD_METHODDEF - SELECT_EPOLL_CLOSE_METHODDEF - SELECT_EPOLL_FILENO_METHODDEF - SELECT_EPOLL_MODIFY_METHODDEF - SELECT_EPOLL_REGISTER_METHODDEF - SELECT_EPOLL_UNREGISTER_METHODDEF - SELECT_EPOLL_POLL_METHODDEF - SELECT_EPOLL___ENTER___METHODDEF - SELECT_EPOLL___EXIT___METHODDEF - {NULL, NULL}, -}; - static PyGetSetDef pyepoll_getsetlist[] = { {"closed", (getter)pyepoll_get_closed, NULL, "True if the epoll handler is closed"}, {0}, }; - -static PyTypeObject pyEpoll_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "select.epoll", /* tp_name */ - sizeof(pyEpoll_Object), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pyepoll_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 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 */ #ifdef HAVE_KQUEUE @@ -2005,48 +1855,6 @@ kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o, Py_RETURN_RICHCOMPARE(result, 0, op); } -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_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - (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 PyObject * kqueue_queue_err_closed(void) { @@ -2364,6 +2172,224 @@ select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist, return NULL; } +static PyGetSetDef kqueue_queue_getsetlist[] = { + {"closed", (getter)kqueue_queue_get_closed, NULL, + "True if the kqueue handler is closed"}, + {0}, +}; + +#endif /* HAVE_KQUEUE */ + + +/* ************************************************************************ */ + +#include "clinic/selectmodule.c.h" + +#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL) + +static PyMethodDef poll_methods[] = { + SELECT_POLL_REGISTER_METHODDEF + SELECT_POLL_MODIFY_METHODDEF + SELECT_POLL_UNREGISTER_METHODDEF + SELECT_POLL_POLL_METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject poll_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.poll", /*tp_name*/ + sizeof(pollObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)poll_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_reserved*/ + 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*/ + poll_methods, /*tp_methods*/ +}; + +#ifdef HAVE_SYS_DEVPOLL_H + +static PyMethodDef devpoll_methods[] = { + {"register", (PyCFunction)devpoll_register, + METH_VARARGS, devpoll_register_doc}, + {"modify", (PyCFunction)devpoll_modify, + METH_VARARGS, devpoll_modify_doc}, + {"unregister", (PyCFunction)devpoll_unregister, + METH_O, devpoll_unregister_doc}, + {"poll", (PyCFunction)devpoll_poll, + METH_VARARGS, devpoll_poll_doc}, + {"close", (PyCFunction)devpoll_close, METH_NOARGS, + devpoll_close_doc}, + {"fileno", (PyCFunction)devpoll_fileno, METH_NOARGS, + devpoll_fileno_doc}, + {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_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_reserved*/ + 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_POLL */ + +#ifdef HAVE_EPOLL + +static PyMethodDef pyepoll_methods[] = { + SELECT_EPOLL_FROMFD_METHODDEF + SELECT_EPOLL_CLOSE_METHODDEF + SELECT_EPOLL_FILENO_METHODDEF + SELECT_EPOLL_MODIFY_METHODDEF + SELECT_EPOLL_REGISTER_METHODDEF + SELECT_EPOLL_UNREGISTER_METHODDEF + SELECT_EPOLL_POLL_METHODDEF + SELECT_EPOLL___ENTER___METHODDEF + SELECT_EPOLL___EXIT___METHODDEF + {NULL, NULL}, +}; + +static PyTypeObject pyEpoll_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "select.epoll", /* tp_name */ + sizeof(pyEpoll_Object), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)pyepoll_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 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 */ + +#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_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (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[] = { SELECT_KQUEUE_FROMFD_METHODDEF SELECT_KQUEUE_CLOSE_METHODDEF @@ -2372,12 +2398,6 @@ static PyMethodDef kqueue_queue_methods[] = { {NULL, NULL}, }; -static PyGetSetDef kqueue_queue_getsetlist[] = { - {"closed", (getter)kqueue_queue_get_closed, NULL, - "True if the kqueue handler is closed"}, - {0}, -}; - static PyTypeObject kqueue_queue_Type = { PyVarObject_HEAD_INIT(NULL, 0) "select.kqueue", /* tp_name */ From 378a27f960d8ecc57193179ca4c8f23e82a16fee Mon Sep 17 00:00:00 2001 From: Tal Einat Date: Wed, 1 Nov 2017 11:52:05 +0200 Subject: [PATCH 04/17] bpo-20182: selectmodule.c AC: add file descriptor argument converter The converter was copied from Modules/posixmodule.c, but changed to check whether fd == -1 rather than fd < 0 as an error condition from calling PyOjbect_AsFileDescriptor(). Note: AC output in Modules/clinic/selectmodule.c.h was manually modified in this commit to get the build working. This may be due to an AC bug. --- Modules/clinic/selectmodule.c.h | 68 ++++++++++++++++---------- Modules/selectmodule.c | 85 ++++++++++++++++----------------- 2 files changed, 83 insertions(+), 70 deletions(-) diff --git a/Modules/clinic/selectmodule.c.h b/Modules/clinic/selectmodule.c.h index 7165755d314f89..529a870d0ba227 100644 --- a/Modules/clinic/selectmodule.c.h +++ b/Modules/clinic/selectmodule.c.h @@ -73,18 +73,17 @@ PyDoc_STRVAR(select_poll_register__doc__, {"register", (PyCFunction)select_poll_register, METH_FASTCALL, select_poll_register__doc__}, static PyObject * -select_poll_register_impl(pollObject *self, PyObject *fd, - unsigned short eventmask); +select_poll_register_impl(pollObject *self, int fd, unsigned short eventmask); static PyObject * select_poll_register(pollObject *self, PyObject **args, Py_ssize_t nargs) { PyObject *return_value = NULL; - PyObject *fd; + int fd; unsigned short eventmask = POLLIN | POLLPRI | POLLOUT; - if (!_PyArg_ParseStack(args, nargs, "O|O&:register", - &fd, ushort_converter, &eventmask)) { + if (!_PyArg_ParseStack(args, nargs, "O&|O&:register", + fildes_converter, &fd, ushort_converter, &eventmask)) { goto exit; } return_value = select_poll_register_impl(self, fd, eventmask); @@ -113,18 +112,17 @@ PyDoc_STRVAR(select_poll_modify__doc__, {"modify", (PyCFunction)select_poll_modify, METH_FASTCALL, select_poll_modify__doc__}, static PyObject * -select_poll_modify_impl(pollObject *self, PyObject *fd, - unsigned short eventmask); +select_poll_modify_impl(pollObject *self, int fd, unsigned short eventmask); static PyObject * select_poll_modify(pollObject *self, PyObject **args, Py_ssize_t nargs) { PyObject *return_value = NULL; - PyObject *fd; + int fd; unsigned short eventmask; - if (!_PyArg_ParseStack(args, nargs, "OO&:modify", - &fd, ushort_converter, &eventmask)) { + if (!_PyArg_ParseStack(args, nargs, "O&O&:modify", + fildes_converter, &fd, ushort_converter, &eventmask)) { goto exit; } return_value = select_poll_modify_impl(self, fd, eventmask); @@ -146,6 +144,24 @@ PyDoc_STRVAR(select_poll_unregister__doc__, #define SELECT_POLL_UNREGISTER_METHODDEF \ {"unregister", (PyCFunction)select_poll_unregister, METH_O, select_poll_unregister__doc__}, +static PyObject * +select_poll_unregister_impl(pollObject *self, int fd); + +static PyObject * +select_poll_unregister(pollObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + + if (!PyArg_Parse(arg, "O&:unregister", fildes_converter, &fd)) { + goto exit; + } + return_value = select_poll_unregister_impl(self, fd); + +exit: + return return_value; +} + #endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) */ #if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) @@ -367,20 +383,19 @@ PyDoc_STRVAR(pyepoll_register__doc__, {"register", (PyCFunction)pyepoll_register, METH_FASTCALL|METH_KEYWORDS, pyepoll_register__doc__}, static PyObject * -pyepoll_register_impl(pyEpoll_Object *self, PyObject *fd, - unsigned int eventmask); +pyepoll_register_impl(pyEpoll_Object *self, int fd, unsigned int eventmask); static PyObject * pyepoll_register(pyEpoll_Object *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; static const char * const _keywords[] = {"fd", "eventmask", NULL}; - static _PyArg_Parser _parser = {"O|I:register", _keywords, 0}; - PyObject *fd; + static _PyArg_Parser _parser = {"O&|I:register", _keywords, 0}; + int fd; unsigned int eventmask = EPOLLIN | EPOLLOUT | EPOLLPRI; if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &fd, &eventmask)) { + fildes_converter, &fd, &eventmask)) { goto exit; } return_value = pyepoll_register_impl(self, fd, eventmask); @@ -408,20 +423,19 @@ PyDoc_STRVAR(pyepoll_modify__doc__, {"modify", (PyCFunction)pyepoll_modify, METH_FASTCALL|METH_KEYWORDS, pyepoll_modify__doc__}, static PyObject * -pyepoll_modify_impl(pyEpoll_Object *self, PyObject *fd, - unsigned int eventmask); +pyepoll_modify_impl(pyEpoll_Object *self, int fd, unsigned int eventmask); static PyObject * pyepoll_modify(pyEpoll_Object *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; static const char * const _keywords[] = {"fd", "eventmask", NULL}; - static _PyArg_Parser _parser = {"OI:modify", _keywords, 0}; - PyObject *fd; + static _PyArg_Parser _parser = {"O&I:modify", _keywords, 0}; + int fd; unsigned int eventmask; if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &fd, &eventmask)) { + fildes_converter, &fd, &eventmask)) { goto exit; } return_value = pyepoll_modify_impl(self, fd, eventmask); @@ -447,18 +461,18 @@ PyDoc_STRVAR(pyepoll_unregister__doc__, {"unregister", (PyCFunction)pyepoll_unregister, METH_FASTCALL|METH_KEYWORDS, pyepoll_unregister__doc__}, static PyObject * -pyepoll_unregister_impl(pyEpoll_Object *self, PyObject *fd); +pyepoll_unregister_impl(pyEpoll_Object *self, int fd); static PyObject * pyepoll_unregister(pyEpoll_Object *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; static const char * const _keywords[] = {"fd", NULL}; - static _PyArg_Parser _parser = {"O:unregister", _keywords, 0}; - PyObject *fd; + static _PyArg_Parser _parser = {"O&:unregister", _keywords, 0}; + int fd; if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &fd)) { + fildes_converter, &fd)) { goto exit; } return_value = pyepoll_unregister_impl(self, fd); @@ -747,6 +761,10 @@ select_kqueue_control(kqueue_queue_Object *self, PyObject **args, Py_ssize_t nar #define SELECT_POLL_POLL_METHODDEF #endif /* !defined(SELECT_POLL_POLL_METHODDEF) */ +#ifndef SELECT_POLL_METHODDEF + #define SELECT_POLL_METHODDEF +#endif /* !defined(SELECT_POLL_METHODDEF) */ + #ifndef SELECT_DEVPOLL_METHODDEF #define SELECT_DEVPOLL_METHODDEF #endif /* !defined(SELECT_DEVPOLL_METHODDEF) */ @@ -774,4 +792,4 @@ select_kqueue_control(kqueue_queue_Object *self, PyObject **args, Py_ssize_t nar #ifndef SELECT_KQUEUE_CONTROL_METHODDEF #define SELECT_KQUEUE_CONTROL_METHODDEF #endif /* !defined(SELECT_KQUEUE_CONTROL_METHODDEF) */ -/*[clinic end generated code: output=9b828bf16401e09e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ce40e8895b08aa75 input=a9049054013a1b77]*/ diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index b48f7cae414708..579d8d4a7d756d 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -66,6 +66,24 @@ class select.kqueue "kqueue_queue_Object *" "&kqueue_queue_Type" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=ec163a60f69bbb6e]*/ +static int +fildes_converter(PyObject *o, void *p) +{ + int fd; + int *pointer = (int *)p; + fd = PyObject_AsFileDescriptor(o); + if (fd == -1) + return 0; + *pointer = fd; + return 1; +} + +/*[python input] +class fildes_converter(CConverter): + type = 'int' + converter = 'fildes_converter' +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=ca54eb5aa476e20a]*/ /* list of Python objects and their file descriptor */ typedef struct { @@ -431,7 +449,7 @@ ushort_converter(PyObject *obj, void *ptr) /*[clinic input] select.poll.register - fd: object + fd: fildes either an integer, or an object with a fileno() method returning an int eventmask: object(converter="ushort_converter", type="unsigned short", c_default="POLLIN | POLLPRI | POLLOUT") = select.POLLIN | select.POLLPRI | select.POLLOUT an optional bitmask describing the type of events to check for @@ -441,21 +459,15 @@ Register a file descriptor with the polling object. [clinic start generated code]*/ static PyObject * -select_poll_register_impl(pollObject *self, PyObject *fd, - unsigned short eventmask) -/*[clinic end generated code: output=9d124fac4c62aa77 input=1eb1ecb69aab929b]*/ +select_poll_register_impl(pollObject *self, int fd, unsigned short eventmask) +/*[clinic end generated code: output=0dc7173c800a4a65 input=be9d277653b257c3]*/ { PyObject *key, *value; - int real_fd; int err; - real_fd = PyObject_AsFileDescriptor(fd); - if (real_fd == -1) - return NULL; - /* Add entry to the internal dictionary: the key is the file descriptor, and the value is the event mask. */ - key = PyLong_FromLong(real_fd); + key = PyLong_FromLong(fd); if (key == NULL) return NULL; value = PyLong_FromLong(eventmask); @@ -478,7 +490,7 @@ select_poll_register_impl(pollObject *self, PyObject *fd, /*[clinic input] select.poll.modify - fd: object + fd: fildes either an integer, or an object with a fileno() method returning an int eventmask: object(converter="ushort_converter", type="unsigned short") @@ -489,19 +501,14 @@ Modify an already registered file descriptor. [clinic start generated code]*/ static PyObject * -select_poll_modify_impl(pollObject *self, PyObject *fd, - unsigned short eventmask) -/*[clinic end generated code: output=427cf336fe49a058 input=981788186a5846ee]*/ +select_poll_modify_impl(pollObject *self, int fd, unsigned short eventmask) +/*[clinic end generated code: output=1a7b88bf079eff17 input=ceabe904d3828b6b]*/ { PyObject *key, *value; - int real_fd; int err; - real_fd = PyObject_AsFileDescriptor(fd); - if (real_fd == -1) return NULL; - /* Modify registered fd */ - key = PyLong_FromLong(real_fd); + key = PyLong_FromLong(fd); if (key == NULL) return NULL; if (PyDict_GetItem(self->dict, key) == NULL) { @@ -530,25 +537,20 @@ select_poll_modify_impl(pollObject *self, PyObject *fd, /*[clinic input] select.poll.unregister - fd: object + fd: fildes / Remove a file descriptor being tracked by the polling object. [clinic start generated code]*/ static PyObject * -select_poll_unregister(pollObject *self, PyObject *fd) -/*[clinic end generated code: output=63e6c416dfc6885c input=69b20d179f588435]*/ +select_poll_unregister_impl(pollObject *self, int fd) +/*[clinic end generated code: output=8c9f42e75e7d291b input=4b4fccc1040e79cb]*/ { PyObject *key; - int real_fd; - - real_fd = PyObject_AsFileDescriptor(fd); - if (real_fd == -1) - return NULL; /* Check whether the fd is already in the array */ - key = PyLong_FromLong(real_fd); + key = PyLong_FromLong(fd); if (key == NULL) return NULL; @@ -1364,7 +1366,7 @@ pyepoll_fromfd_impl(PyTypeObject *type, int fd) static PyObject * -pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events) +pyepoll_internal_ctl(int epfd, int op, int fd, unsigned int events) { struct epoll_event ev; int result; @@ -1373,11 +1375,6 @@ pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events) if (epfd < 0) return pyepoll_err_closed(); - fd = PyObject_AsFileDescriptor(pfd); - if (fd == -1) { - return NULL; - } - switch (op) { case EPOLL_CTL_ADD: case EPOLL_CTL_MOD: @@ -1415,7 +1412,7 @@ pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events) /*[clinic input] select.epoll.register as pyepoll_register - fd: object + fd: fildes the target file descriptor of the operation eventmask: unsigned_int(c_default="EPOLLIN | EPOLLOUT | EPOLLPRI", bitwise=True) = EPOLLIN | EPOLLOUT | EPOLLPRI a bit set composed of the various EPOLL constants @@ -1426,9 +1423,8 @@ The epoll interface supports all file descriptors that support poll. [clinic start generated code]*/ static PyObject * -pyepoll_register_impl(pyEpoll_Object *self, PyObject *fd, - unsigned int eventmask) -/*[clinic end generated code: output=7c03082c701b4386 input=7598971f10e2b318]*/ +pyepoll_register_impl(pyEpoll_Object *self, int fd, unsigned int eventmask) +/*[clinic end generated code: output=3244c166875dda1f input=a2dcd94e3b1692d6]*/ { return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, fd, eventmask); } @@ -1436,7 +1432,7 @@ pyepoll_register_impl(pyEpoll_Object *self, PyObject *fd, /*[clinic input] select.epoll.modify as pyepoll_modify - fd: object + fd: fildes the target file descriptor of the operation eventmask: unsigned_int(bitwise=True) a bit set composed of the various EPOLL constants @@ -1445,9 +1441,8 @@ Modify event mask for a registered file descriptor. [clinic start generated code]*/ static PyObject * -pyepoll_modify_impl(pyEpoll_Object *self, PyObject *fd, - unsigned int eventmask) -/*[clinic end generated code: output=3d18cbb713866267 input=107c7ca76f0af422]*/ +pyepoll_modify_impl(pyEpoll_Object *self, int fd, unsigned int eventmask) +/*[clinic end generated code: output=5d5093932bbf9234 input=17ba4cf5230fe7e1]*/ { return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, fd, eventmask); } @@ -1455,15 +1450,15 @@ pyepoll_modify_impl(pyEpoll_Object *self, PyObject *fd, /*[clinic input] select.epoll.unregister as pyepoll_unregister - fd: object + fd: fildes the target file descriptor of the operation Remove a registered file descriptor from the epoll object. [clinic start generated code]*/ static PyObject * -pyepoll_unregister_impl(pyEpoll_Object *self, PyObject *fd) -/*[clinic end generated code: output=83dac1817f807c2d input=39795651cc232dec]*/ +pyepoll_unregister_impl(pyEpoll_Object *self, int fd) +/*[clinic end generated code: output=539abcb9ec95f6b8 input=35b3cebfae5cbc12]*/ { return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, fd, 0); } From fc964f08ae757883381d6ce2980da32ca02ebada Mon Sep 17 00:00:00 2001 From: Tal Einat Date: Wed, 1 Nov 2017 11:58:05 +0200 Subject: [PATCH 05/17] bpo-20182: selectmodule.c AC: convert select.devpoll to AC Note: AC output in Modules/clinic/selectmodule.c.h was manually modified in this commit to get the build working. This may be due to an AC bug. --- Modules/clinic/selectmodule.c.h | 212 ++++++++++++++++++++++++++++++-- Modules/selectmodule.c | 153 ++++++++++++----------- 2 files changed, 287 insertions(+), 78 deletions(-) diff --git a/Modules/clinic/selectmodule.c.h b/Modules/clinic/selectmodule.c.h index 529a870d0ba227..6dacfcb3da422d 100644 --- a/Modules/clinic/selectmodule.c.h +++ b/Modules/clinic/selectmodule.c.h @@ -200,6 +200,200 @@ select_poll_poll(pollObject *self, PyObject **args, Py_ssize_t nargs) #endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) */ +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) + +PyDoc_STRVAR(select_devpoll_register__doc__, +"register($self, fd, eventmask=POLLIN | POLLOUT | POLLPRI, /)\n" +"--\n" +"\n" +"Register a file descriptor with the polling object.\n" +"\n" +" fd\n" +" either an integer, or an object with a fileno() method returning\n" +" an int\n" +" eventmask\n" +" an optional bitmask describing the type of events to check for"); + +#define SELECT_DEVPOLL_REGISTER_METHODDEF \ + {"register", (PyCFunction)select_devpoll_register, METH_FASTCALL, select_devpoll_register__doc__}, + +static PyObject * +select_devpoll_register_impl(devpollObject *self, int fd, + unsigned short eventmask); + +static PyObject * +select_devpoll_register(devpollObject *self, PyObject **args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + unsigned short eventmask = POLLIN | POLLOUT | POLLPRI; + + if (!_PyArg_ParseStack(args, nargs, "O&|H:register", + fildes_converter, &fd, &eventmask)) { + goto exit; + } + return_value = select_devpoll_register_impl(self, fd, eventmask); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) + +PyDoc_STRVAR(select_devpoll_modify__doc__, +"modify($self, fd, eventmask=POLLIN | POLLOUT | POLLPRI, /)\n" +"--\n" +"\n" +"Modify a possible already registered file descriptor.\n" +"\n" +" fd\n" +" either an integer, or an object with a fileno() method returning\n" +" an int\n" +" eventmask\n" +" an optional bitmask describing the type of events to check for"); + +#define SELECT_DEVPOLL_MODIFY_METHODDEF \ + {"modify", (PyCFunction)select_devpoll_modify, METH_FASTCALL, select_devpoll_modify__doc__}, + +static PyObject * +select_devpoll_modify_impl(devpollObject *self, int fd, + unsigned short eventmask); + +static PyObject * +select_devpoll_modify(devpollObject *self, PyObject **args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + unsigned short eventmask = POLLIN | POLLOUT | POLLPRI; + + if (!_PyArg_ParseStack(args, nargs, "O&|H:modify", + fildes_converter, &fd, &eventmask)) { + goto exit; + } + return_value = select_devpoll_modify_impl(self, fd, eventmask); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) + +PyDoc_STRVAR(select_devpoll_unregister__doc__, +"unregister($self, fd, /)\n" +"--\n" +"\n" +"Remove a file descriptor being tracked by the polling object."); + +#define SELECT_DEVPOLL_UNREGISTER_METHODDEF \ + {"unregister", (PyCFunction)select_devpoll_unregister, METH_O, select_devpoll_unregister__doc__}, + +static PyObject * +select_devpoll_unregister_impl(devpollObject *self, int fd); + +static PyObject * +select_devpoll_unregister(devpollObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + + if (!PyArg_Parse(arg, "O&:unregister", fildes_converter, &fd)) { + goto exit; + } + return_value = select_devpoll_unregister_impl(self, fd); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) + +PyDoc_STRVAR(select_devpoll_poll__doc__, +"poll($self, /, timeout=None)\n" +"--\n" +"\n" +"Polls the set of registered file descriptors.\n" +"\n" +"Returns a list containing any descriptors that have events or errors to\n" +"report."); + +#define SELECT_DEVPOLL_POLL_METHODDEF \ + {"poll", (PyCFunction)select_devpoll_poll, METH_FASTCALL|METH_KEYWORDS, select_devpoll_poll__doc__}, + +static PyObject * +select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj); + +static PyObject * +select_devpoll_poll(devpollObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"timeout", NULL}; + static _PyArg_Parser _parser = {"|O:poll", _keywords, 0}; + PyObject *timeout_obj = Py_None; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &timeout_obj)) { + goto exit; + } + return_value = select_devpoll_poll_impl(self, timeout_obj); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) + +PyDoc_STRVAR(select_devpoll_close__doc__, +"close($self, /)\n" +"--\n" +"\n" +"Close the devpoll file descriptor.\n" +"\n" +"Further operations on the devpoll object will raise an exception."); + +#define SELECT_DEVPOLL_CLOSE_METHODDEF \ + {"close", (PyCFunction)select_devpoll_close, METH_NOARGS, select_devpoll_close__doc__}, + +static PyObject * +select_devpoll_close_impl(devpollObject *self); + +static PyObject * +select_devpoll_close(devpollObject *self, PyObject *Py_UNUSED(ignored)) +{ + return select_devpoll_close_impl(self); +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) + +PyDoc_STRVAR(select_devpoll_fileno__doc__, +"fileno($self, /)\n" +"--\n" +"\n" +"Return the file descriptor."); + +#define SELECT_DEVPOLL_FILENO_METHODDEF \ + {"fileno", (PyCFunction)select_devpoll_fileno, METH_NOARGS, select_devpoll_fileno__doc__}, + +static PyObject * +select_devpoll_fileno_impl(devpollObject *self); + +static PyObject * +select_devpoll_fileno(devpollObject *self, PyObject *Py_UNUSED(ignored)) +{ + return select_devpoll_fileno_impl(self); +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ + #if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) PyDoc_STRVAR(select_poll__doc__, @@ -765,18 +959,18 @@ select_kqueue_control(kqueue_queue_Object *self, PyObject **args, Py_ssize_t nar #define SELECT_POLL_METHODDEF #endif /* !defined(SELECT_POLL_METHODDEF) */ +#ifndef SELECT_DEVPOLL_CLOSE_METHODDEF + #define SELECT_DEVPOLL_CLOSE_METHODDEF +#endif /* !defined(SELECT_DEVPOLL_CLOSE_METHODDEF) */ + +#ifndef SELECT_DEVPOLL_FILENO_METHODDEF + #define SELECT_DEVPOLL_FILENO_METHODDEF +#endif /* !defined(SELECT_DEVPOLL_FILENO_METHODDEF) */ + #ifndef SELECT_DEVPOLL_METHODDEF #define SELECT_DEVPOLL_METHODDEF #endif /* !defined(SELECT_DEVPOLL_METHODDEF) */ -#ifndef PYEPOLL_CLOSE_METHODDEF - #define PYEPOLL_CLOSE_METHODDEF -#endif /* !defined(PYEPOLL_CLOSE_METHODDEF) */ - -#ifndef PYEPOLL_FILENO_METHODDEF - #define PYEPOLL_FILENO_METHODDEF -#endif /* !defined(PYEPOLL_FILENO_METHODDEF) */ - #ifndef PYEPOLL_FROMFD_METHODDEF #define PYEPOLL_FROMFD_METHODDEF #endif /* !defined(PYEPOLL_FROMFD_METHODDEF) */ @@ -792,4 +986,4 @@ select_kqueue_control(kqueue_queue_Object *self, PyObject **args, Py_ssize_t nar #ifndef SELECT_KQUEUE_CONTROL_METHODDEF #define SELECT_KQUEUE_CONTROL_METHODDEF #endif /* !defined(SELECT_KQUEUE_CONTROL_METHODDEF) */ -/*[clinic end generated code: output=ce40e8895b08aa75 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d7ac485af4c76371 input=a9049054013a1b77]*/ diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 579d8d4a7d756d..99a4d212bf29d0 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -61,10 +61,11 @@ extern void bzero(void *, int); /*[clinic input] module select class select.poll "pollObject *" "&poll_Type" +class select.devpoll "devpollObject *" "&devpoll_Type" class select.epoll "pyEpoll_Object *" "&pyEpoll_Type" class select.kqueue "kqueue_queue_Object *" "&kqueue_queue_Type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ec163a60f69bbb6e]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ded80abdad2b7552]*/ static int fildes_converter(PyObject *o, void *p) @@ -797,21 +798,12 @@ static int devpoll_flush(devpollObject *self) } static PyObject * -internal_devpoll_register(devpollObject *self, PyObject *args, int remove) +internal_devpoll_register(devpollObject *self, int fd, + unsigned short events, int remove) { - PyObject *o; - int fd; - unsigned short events = POLLIN | POLLPRI | POLLOUT; - if (self->fd_devpoll < 0) return devpoll_err_closed(); - if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events)) - return NULL; - - fd = PyObject_AsFileDescriptor(o); - if (fd == -1) return NULL; - if (remove) { self->fds[self->n_fds].fd = fd; self->fds[self->n_fds].events = POLLREMOVE; @@ -833,49 +825,66 @@ internal_devpoll_register(devpollObject *self, PyObject *args, int remove) Py_RETURN_NONE; } -PyDoc_STRVAR(devpoll_register_doc, -"register(fd [, eventmask] ) -> None\n\n\ -Register a file descriptor with the polling object.\n\ -fd -- either an integer, or an object with a fileno() method returning an\n\ - int.\n\ -events -- an optional bitmask describing the type of events to check for"); +/*[clinic input] +select.devpoll.register + + fd: fildes + either an integer, or an object with a fileno() method returning + an int + eventmask: unsigned_short(c_default="POLLIN | POLLOUT | POLLPRI", bitwise=True) = POLLIN | POLLOUT | POLLPRI + an optional bitmask describing the type of events to check for + / + +Register a file descriptor with the polling object. +[clinic start generated code]*/ static PyObject * -devpoll_register(devpollObject *self, PyObject *args) +select_devpoll_register_impl(devpollObject *self, int fd, + unsigned short eventmask) +/*[clinic end generated code: output=6e07fe8b74abba0c input=e05806bf7dbe3d40]*/ { - return internal_devpoll_register(self, args, 0); + return internal_devpoll_register(self, fd, eventmask, 0); } -PyDoc_STRVAR(devpoll_modify_doc, -"modify(fd[, eventmask]) -> None\n\n\ -Modify a possible already registered file descriptor.\n\ -fd -- either an integer, or an object with a fileno() method returning an\n\ - int.\n\ -events -- an optional bitmask describing the type of events to check for"); +/*[clinic input] +select.devpoll.modify + + fd: fildes + either an integer, or an object with a fileno() method returning + an int + eventmask: unsigned_short(c_default="POLLIN | POLLOUT | POLLPRI", bitwise=True) = POLLIN | POLLOUT | POLLPRI + an optional bitmask describing the type of events to check for + / +Modify a possible already registered file descriptor. +[clinic start generated code]*/ + +static PyObject * +select_devpoll_modify_impl(devpollObject *self, int fd, + unsigned short eventmask) +/*[clinic end generated code: output=bc2e6d23aaff98b4 input=bfa967d0abd1c48c]*/ static PyObject * devpoll_modify(devpollObject *self, PyObject *args) { - return internal_devpoll_register(self, args, 1); + return internal_devpoll_register(self, fd, eventmask, 1); } +/*[clinic input] +select.devpoll.unregister + + fd: fildes + / -PyDoc_STRVAR(devpoll_unregister_doc, -"unregister(fd) -> None\n\n\ -Remove a file descriptor being tracked by the polling object."); +Remove a file descriptor being tracked by the polling object. +[clinic start generated code]*/ static PyObject * -devpoll_unregister(devpollObject *self, PyObject *o) +select_devpoll_unregister_impl(devpollObject *self, int fd) +/*[clinic end generated code: output=95519ffa0c7d43fe input=b4ea42a4442fd467]*/ { - int fd; - if (self->fd_devpoll < 0) return devpoll_err_closed(); - fd = PyObject_AsFileDescriptor( o ); - if (fd == -1) - return NULL; - self->fds[self->n_fds].fd = fd; self->fds[self->n_fds].events = POLLREMOVE; @@ -887,13 +896,20 @@ devpoll_unregister(devpollObject *self, PyObject *o) Py_RETURN_NONE; } -PyDoc_STRVAR(devpoll_poll_doc, -"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\ -Polls the set of registered file descriptors, returning a list containing \n\ -any descriptors that have events or errors to report."); +/*[clinic input] +select.devpoll.poll + + timeout as timeout_obj: object = None + +Polls the set of registered file descriptors. + +Returns a list containing any descriptors that have events or errors to +report. +[clinic start generated code]*/ static PyObject * -devpoll_poll(devpollObject *self, PyObject *args) +select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj) +/*[clinic end generated code: output=2654e5457cca0b3c input=fecb272f2f670025]*/ { struct dvpoll dvp; PyObject *result_list = NULL, *timeout_obj = NULL; @@ -1013,8 +1029,17 @@ devpoll_internal_close(devpollObject *self) return save_errno; } -static PyObject* -devpoll_close(devpollObject *self) +/*[clinic input] +select.devpoll.close + +Close the devpoll file descriptor. + +Further operations on the devpoll object will raise an exception. +[clinic start generated code]*/ + +static PyObject * +select_devpoll_close_impl(devpollObject *self) +/*[clinic end generated code: output=26b355bd6429f21b input=6273c30f5560a99b]*/ { errno = devpoll_internal_close(self); if (errno < 0) { @@ -1024,12 +1049,6 @@ devpoll_close(devpollObject *self) Py_RETURN_NONE; } -PyDoc_STRVAR(devpoll_close_doc, -"close() -> None\n\ -\n\ -Close the devpoll file descriptor. Further operations on the devpoll\n\ -object will raise an exception."); - static PyObject* devpoll_get_closed(devpollObject *self) { @@ -1039,19 +1058,21 @@ devpoll_get_closed(devpollObject *self) Py_RETURN_FALSE; } -static PyObject* -devpoll_fileno(devpollObject *self) +/*[clinic input] +select.devpoll.fileno + +Return the file descriptor. +[clinic start generated code]*/ + +static PyObject * +select_devpoll_fileno_impl(devpollObject *self) +/*[clinic end generated code: output=26920929f8d292f4 input=ef15331ebde6c368]*/ { if (self->fd_devpoll < 0) return devpoll_err_closed(); return PyLong_FromLong(self->fd_devpoll); } -PyDoc_STRVAR(devpoll_fileno_doc, -"fileno() -> int\n\ -\n\ -Return the file descriptor."); - static PyGetSetDef devpoll_getsetlist[] = { {"closed", (getter)devpoll_get_closed, NULL, "True if the devpoll object is closed"}, @@ -2227,18 +2248,12 @@ static PyTypeObject poll_Type = { #ifdef HAVE_SYS_DEVPOLL_H static PyMethodDef devpoll_methods[] = { - {"register", (PyCFunction)devpoll_register, - METH_VARARGS, devpoll_register_doc}, - {"modify", (PyCFunction)devpoll_modify, - METH_VARARGS, devpoll_modify_doc}, - {"unregister", (PyCFunction)devpoll_unregister, - METH_O, devpoll_unregister_doc}, - {"poll", (PyCFunction)devpoll_poll, - METH_VARARGS, devpoll_poll_doc}, - {"close", (PyCFunction)devpoll_close, METH_NOARGS, - devpoll_close_doc}, - {"fileno", (PyCFunction)devpoll_fileno, METH_NOARGS, - devpoll_fileno_doc}, + SELECT_DEVPOLL_REGISTER_METHODDEF + SELECT_DEVPOLL_MODIFY_METHODDEF + SELECT_DEVPOLL_UNREGISTER_METHODDEF + SELECT_DEVPOLL_POLL_METHODDEF + SELECT_DEVPOLL_CLOSE_METHODDEF + SELECT_DEVPOLL_FILENO_METHODDEF {NULL, NULL} /* sentinel */ }; From b415d95fbd9963044420c1ce2f4e6b4c762b250e Mon Sep 17 00:00:00 2001 From: Tal Einat Date: Wed, 1 Nov 2017 12:03:13 +0200 Subject: [PATCH 06/17] bpo-20182: selectmodule.c AC: fix and standardize use of ushort_converter --- Modules/clinic/selectmodule.c.h | 25 ++++++++++--------------- Modules/selectmodule.c | 22 +++++++++++----------- 2 files changed, 21 insertions(+), 26 deletions(-) diff --git a/Modules/clinic/selectmodule.c.h b/Modules/clinic/selectmodule.c.h index 6dacfcb3da422d..790d4206cdb73e 100644 --- a/Modules/clinic/selectmodule.c.h +++ b/Modules/clinic/selectmodule.c.h @@ -58,8 +58,7 @@ select_select(PyObject *module, PyObject **args, Py_ssize_t nargs) #if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) PyDoc_STRVAR(select_poll_register__doc__, -"register($self, fd,\n" -" eventmask=select.POLLIN | select.POLLPRI | select.POLLOUT, /)\n" +"register($self, fd, eventmask=POLLIN | POLLOUT | POLLPRI, /)\n" "--\n" "\n" "Register a file descriptor with the polling object.\n" @@ -80,7 +79,7 @@ select_poll_register(pollObject *self, PyObject **args, Py_ssize_t nargs) { PyObject *return_value = NULL; int fd; - unsigned short eventmask = POLLIN | POLLPRI | POLLOUT; + unsigned short eventmask = POLLIN | POLLOUT | POLLPRI; if (!_PyArg_ParseStack(args, nargs, "O&|O&:register", fildes_converter, &fd, ushort_converter, &eventmask)) { @@ -106,7 +105,7 @@ PyDoc_STRVAR(select_poll_modify__doc__, " either an integer, or an object with a fileno() method returning\n" " an int\n" " eventmask\n" -" an optional bitmask describing the type of events to check for"); +" a bitmask describing the type of events to check for"); #define SELECT_POLL_MODIFY_METHODDEF \ {"modify", (PyCFunction)select_poll_modify, METH_FASTCALL, select_poll_modify__doc__}, @@ -172,8 +171,8 @@ PyDoc_STRVAR(select_poll_poll__doc__, "\n" "Polls the set of registered file descriptors.\n" "\n" -"Returns a list containing any descriptors that have events or errors to report,\n" -"as a list of (fd, event) 2-tuples."); +"Returns a list containing any descriptors that have events or errors to\n" +"report, as a list of (fd, event) 2-tuples."); #define SELECT_POLL_POLL_METHODDEF \ {"poll", (PyCFunction)select_poll_poll, METH_FASTCALL, select_poll_poll__doc__}, @@ -228,8 +227,8 @@ select_devpoll_register(devpollObject *self, PyObject **args, Py_ssize_t nargs) int fd; unsigned short eventmask = POLLIN | POLLOUT | POLLPRI; - if (!_PyArg_ParseStack(args, nargs, "O&|H:register", - fildes_converter, &fd, &eventmask)) { + if (!_PyArg_ParseStack(args, nargs, "O&|O&:register", + fildes_converter, &fd, ushort_converter, &eventmask)) { goto exit; } return_value = select_devpoll_register_impl(self, fd, eventmask); @@ -268,8 +267,8 @@ select_devpoll_modify(devpollObject *self, PyObject **args, Py_ssize_t nargs) int fd; unsigned short eventmask = POLLIN | POLLOUT | POLLPRI; - if (!_PyArg_ParseStack(args, nargs, "O&|H:modify", - fildes_converter, &fd, &eventmask)) { + if (!_PyArg_ParseStack(args, nargs, "O&|O&:modify", + fildes_converter, &fd, ushort_converter, &eventmask)) { goto exit; } return_value = select_devpoll_modify_impl(self, fd, eventmask); @@ -955,10 +954,6 @@ select_kqueue_control(kqueue_queue_Object *self, PyObject **args, Py_ssize_t nar #define SELECT_POLL_POLL_METHODDEF #endif /* !defined(SELECT_POLL_POLL_METHODDEF) */ -#ifndef SELECT_POLL_METHODDEF - #define SELECT_POLL_METHODDEF -#endif /* !defined(SELECT_POLL_METHODDEF) */ - #ifndef SELECT_DEVPOLL_CLOSE_METHODDEF #define SELECT_DEVPOLL_CLOSE_METHODDEF #endif /* !defined(SELECT_DEVPOLL_CLOSE_METHODDEF) */ @@ -986,4 +981,4 @@ select_kqueue_control(kqueue_queue_Object *self, PyObject **args, Py_ssize_t nar #ifndef SELECT_KQUEUE_CONTROL_METHODDEF #define SELECT_KQUEUE_CONTROL_METHODDEF #endif /* !defined(SELECT_KQUEUE_CONTROL_METHODDEF) */ -/*[clinic end generated code: output=d7ac485af4c76371 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=fd52937a289a6697 input=a9049054013a1b77]*/ diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 99a4d212bf29d0..c545c5da44f797 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -452,7 +452,7 @@ select.poll.register fd: fildes either an integer, or an object with a fileno() method returning an int - eventmask: object(converter="ushort_converter", type="unsigned short", c_default="POLLIN | POLLPRI | POLLOUT") = select.POLLIN | select.POLLPRI | select.POLLOUT + eventmask: object(converter="ushort_converter", type="unsigned short", c_default="POLLIN | POLLOUT | POLLPRI") = POLLIN | POLLOUT | POLLPRI an optional bitmask describing the type of events to check for / @@ -461,7 +461,7 @@ Register a file descriptor with the polling object. static PyObject * select_poll_register_impl(pollObject *self, int fd, unsigned short eventmask) -/*[clinic end generated code: output=0dc7173c800a4a65 input=be9d277653b257c3]*/ +/*[clinic end generated code: output=0dc7173c800a4a65 input=e20f283a8250fb5e]*/ { PyObject *key, *value; int err; @@ -495,7 +495,7 @@ select.poll.modify either an integer, or an object with a fileno() method returning an int eventmask: object(converter="ushort_converter", type="unsigned short") - an optional bitmask describing the type of events to check for + a bitmask describing the type of events to check for / Modify an already registered file descriptor. @@ -503,7 +503,7 @@ Modify an already registered file descriptor. static PyObject * select_poll_modify_impl(pollObject *self, int fd, unsigned short eventmask) -/*[clinic end generated code: output=1a7b88bf079eff17 input=ceabe904d3828b6b]*/ +/*[clinic end generated code: output=1a7b88bf079eff17 input=b8e0e04a1264b78f]*/ { PyObject *key, *value; int err; @@ -576,13 +576,13 @@ select.poll.poll Polls the set of registered file descriptors. -Returns a list containing any descriptors that have events or errors to report, -as a list of (fd, event) 2-tuples. +Returns a list containing any descriptors that have events or errors to +report, as a list of (fd, event) 2-tuples. [clinic start generated code]*/ static PyObject * select_poll_poll_impl(pollObject *self, PyObject *timeout_obj) -/*[clinic end generated code: output=876e837d193ed7e4 input=65e7913e6a7d2754]*/ +/*[clinic end generated code: output=876e837d193ed7e4 input=7a446ed45189e894]*/ { PyObject *result_list = NULL; int poll_result, i, j; @@ -831,7 +831,7 @@ select.devpoll.register fd: fildes either an integer, or an object with a fileno() method returning an int - eventmask: unsigned_short(c_default="POLLIN | POLLOUT | POLLPRI", bitwise=True) = POLLIN | POLLOUT | POLLPRI + eventmask: object(converter="ushort_converter", type="unsigned short", c_default="POLLIN | POLLOUT | POLLPRI") = POLLIN | POLLOUT | POLLPRI an optional bitmask describing the type of events to check for / @@ -841,7 +841,7 @@ Register a file descriptor with the polling object. static PyObject * select_devpoll_register_impl(devpollObject *self, int fd, unsigned short eventmask) -/*[clinic end generated code: output=6e07fe8b74abba0c input=e05806bf7dbe3d40]*/ +/*[clinic end generated code: output=6e07fe8b74abba0c input=c6bed777bd69a7bc]*/ { return internal_devpoll_register(self, fd, eventmask, 0); } @@ -852,7 +852,7 @@ select.devpoll.modify fd: fildes either an integer, or an object with a fileno() method returning an int - eventmask: unsigned_short(c_default="POLLIN | POLLOUT | POLLPRI", bitwise=True) = POLLIN | POLLOUT | POLLPRI + eventmask: object(converter="ushort_converter", type="unsigned short", c_default="POLLIN | POLLOUT | POLLPRI") = POLLIN | POLLOUT | POLLPRI an optional bitmask describing the type of events to check for / @@ -862,7 +862,7 @@ Modify a possible already registered file descriptor. static PyObject * select_devpoll_modify_impl(devpollObject *self, int fd, unsigned short eventmask) -/*[clinic end generated code: output=bc2e6d23aaff98b4 input=bfa967d0abd1c48c]*/ +/*[clinic end generated code: output=bc2e6d23aaff98b4 input=2d8e3ddaa722656c]*/ static PyObject * devpoll_modify(devpollObject *self, PyObject *args) { From 352004cc735f712f25ed860c660e87d5f5f42e75 Mon Sep 17 00:00:00 2001 From: Tal Einat Date: Wed, 1 Nov 2017 12:20:54 +0200 Subject: [PATCH 07/17] bpo-20182: selectmodule.c AC: don't "as"-rename epoll method functions Also change the doc-string of epoll.poll: * use AC's per-argument docs to describe the arguments * revert an addition describing the return value Note: AC output in Modules/clinic/selectmodule.c.h was manually modified in this commit to get the build working. This may be due to an AC bug. --- Modules/clinic/selectmodule.c.h | 151 ++++++++++++++++---------------- Modules/selectmodule.c | 74 ++++++++-------- 2 files changed, 114 insertions(+), 111 deletions(-) diff --git a/Modules/clinic/selectmodule.c.h b/Modules/clinic/selectmodule.c.h index 790d4206cdb73e..8949ae1762552a 100644 --- a/Modules/clinic/selectmodule.c.h +++ b/Modules/clinic/selectmodule.c.h @@ -445,7 +445,7 @@ select_devpoll(PyObject *module, PyObject *Py_UNUSED(ignored)) #if defined(HAVE_EPOLL) -PyDoc_STRVAR(pyepoll_new__doc__, +PyDoc_STRVAR(select_epoll__doc__, "epoll(sizehint=-1, flags=0)\n" "--\n" "\n" @@ -457,10 +457,10 @@ PyDoc_STRVAR(pyepoll_new__doc__, " the maximum number of monitored events."); static PyObject * -pyepoll_new_impl(PyTypeObject *type, int sizehint, int flags); +select_epoll_impl(PyTypeObject *type, int sizehint, int flags); static PyObject * -pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +select_epoll(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; static const char * const _keywords[] = {"sizehint", "flags", NULL}; @@ -472,7 +472,7 @@ pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) &sizehint, &flags)) { goto exit; } - return_value = pyepoll_new_impl(type, sizehint, flags); + return_value = select_epoll_impl(type, sizehint, flags); exit: return return_value; @@ -482,7 +482,7 @@ pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) #if defined(HAVE_EPOLL) -PyDoc_STRVAR(pyepoll_close__doc__, +PyDoc_STRVAR(select_epoll_close__doc__, "close($self, /)\n" "--\n" "\n" @@ -490,58 +490,58 @@ PyDoc_STRVAR(pyepoll_close__doc__, "\n" "Further operations on the epoll object will raise an exception."); -#define PYEPOLL_CLOSE_METHODDEF \ - {"close", (PyCFunction)pyepoll_close, METH_NOARGS, pyepoll_close__doc__}, +#define SELECT_EPOLL_CLOSE_METHODDEF \ + {"close", (PyCFunction)select_epoll_close, METH_NOARGS, select_epoll_close__doc__}, static PyObject * -pyepoll_close_impl(pyEpoll_Object *self); +select_epoll_close_impl(pyEpoll_Object *self); static PyObject * -pyepoll_close(pyEpoll_Object *self, PyObject *Py_UNUSED(ignored)) +select_epoll_close(pyEpoll_Object *self, PyObject *Py_UNUSED(ignored)) { - return pyepoll_close_impl(self); + return select_epoll_close_impl(self); } #endif /* defined(HAVE_EPOLL) */ #if defined(HAVE_EPOLL) -PyDoc_STRVAR(pyepoll_fileno__doc__, +PyDoc_STRVAR(select_epoll_fileno__doc__, "fileno($self, /)\n" "--\n" "\n" "Return the epoll control file descriptor."); -#define PYEPOLL_FILENO_METHODDEF \ - {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS, pyepoll_fileno__doc__}, +#define SELECT_EPOLL_FILENO_METHODDEF \ + {"fileno", (PyCFunction)select_epoll_fileno, METH_NOARGS, select_epoll_fileno__doc__}, static PyObject * -pyepoll_fileno_impl(pyEpoll_Object *self); +select_epoll_fileno_impl(pyEpoll_Object *self); static PyObject * -pyepoll_fileno(pyEpoll_Object *self, PyObject *Py_UNUSED(ignored)) +select_epoll_fileno(pyEpoll_Object *self, PyObject *Py_UNUSED(ignored)) { - return pyepoll_fileno_impl(self); + return select_epoll_fileno_impl(self); } #endif /* defined(HAVE_EPOLL) */ #if defined(HAVE_EPOLL) -PyDoc_STRVAR(pyepoll_fromfd__doc__, +PyDoc_STRVAR(select_epoll_fromfd__doc__, "fromfd($type, fd, /)\n" "--\n" "\n" "Create an epoll object from a given control fd."); -#define PYEPOLL_FROMFD_METHODDEF \ - {"fromfd", (PyCFunction)pyepoll_fromfd, METH_O|METH_CLASS, pyepoll_fromfd__doc__}, +#define SELECT_EPOLL_FROMFD_METHODDEF \ + {"fromfd", (PyCFunction)select_epoll_fromfd, METH_O|METH_CLASS, select_epoll_fromfd__doc__}, static PyObject * -pyepoll_fromfd_impl(PyTypeObject *type, int fd); +select_epoll_fromfd_impl(PyTypeObject *type, int fd); static PyObject * -pyepoll_fromfd(PyTypeObject *type, PyObject *arg) +select_epoll_fromfd(PyTypeObject *type, PyObject *arg) { PyObject *return_value = NULL; int fd; @@ -549,7 +549,7 @@ pyepoll_fromfd(PyTypeObject *type, PyObject *arg) if (!PyArg_Parse(arg, "i:fromfd", &fd)) { goto exit; } - return_value = pyepoll_fromfd_impl(type, fd); + return_value = select_epoll_fromfd_impl(type, fd); exit: return return_value; @@ -559,7 +559,7 @@ pyepoll_fromfd(PyTypeObject *type, PyObject *arg) #if defined(HAVE_EPOLL) -PyDoc_STRVAR(pyepoll_register__doc__, +PyDoc_STRVAR(select_epoll_register__doc__, "register($self, /, fd, eventmask=EPOLLIN | EPOLLOUT | EPOLLPRI)\n" "--\n" "\n" @@ -572,14 +572,15 @@ PyDoc_STRVAR(pyepoll_register__doc__, "\n" "The epoll interface supports all file descriptors that support poll."); -#define PYEPOLL_REGISTER_METHODDEF \ - {"register", (PyCFunction)pyepoll_register, METH_FASTCALL|METH_KEYWORDS, pyepoll_register__doc__}, +#define SELECT_EPOLL_REGISTER_METHODDEF \ + {"register", (PyCFunction)select_epoll_register, METH_FASTCALL|METH_KEYWORDS, select_epoll_register__doc__}, static PyObject * -pyepoll_register_impl(pyEpoll_Object *self, int fd, unsigned int eventmask); +select_epoll_register_impl(pyEpoll_Object *self, int fd, + unsigned int eventmask); static PyObject * -pyepoll_register(pyEpoll_Object *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) +select_epoll_register(pyEpoll_Object *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; static const char * const _keywords[] = {"fd", "eventmask", NULL}; @@ -591,7 +592,7 @@ pyepoll_register(pyEpoll_Object *self, PyObject **args, Py_ssize_t nargs, PyObje fildes_converter, &fd, &eventmask)) { goto exit; } - return_value = pyepoll_register_impl(self, fd, eventmask); + return_value = select_epoll_register_impl(self, fd, eventmask); exit: return return_value; @@ -601,7 +602,7 @@ pyepoll_register(pyEpoll_Object *self, PyObject **args, Py_ssize_t nargs, PyObje #if defined(HAVE_EPOLL) -PyDoc_STRVAR(pyepoll_modify__doc__, +PyDoc_STRVAR(select_epoll_modify__doc__, "modify($self, /, fd, eventmask)\n" "--\n" "\n" @@ -612,14 +613,15 @@ PyDoc_STRVAR(pyepoll_modify__doc__, " eventmask\n" " a bit set composed of the various EPOLL constants"); -#define PYEPOLL_MODIFY_METHODDEF \ - {"modify", (PyCFunction)pyepoll_modify, METH_FASTCALL|METH_KEYWORDS, pyepoll_modify__doc__}, +#define SELECT_EPOLL_MODIFY_METHODDEF \ + {"modify", (PyCFunction)select_epoll_modify, METH_FASTCALL|METH_KEYWORDS, select_epoll_modify__doc__}, static PyObject * -pyepoll_modify_impl(pyEpoll_Object *self, int fd, unsigned int eventmask); +select_epoll_modify_impl(pyEpoll_Object *self, int fd, + unsigned int eventmask); static PyObject * -pyepoll_modify(pyEpoll_Object *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) +select_epoll_modify(pyEpoll_Object *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; static const char * const _keywords[] = {"fd", "eventmask", NULL}; @@ -631,7 +633,7 @@ pyepoll_modify(pyEpoll_Object *self, PyObject **args, Py_ssize_t nargs, PyObject fildes_converter, &fd, &eventmask)) { goto exit; } - return_value = pyepoll_modify_impl(self, fd, eventmask); + return_value = select_epoll_modify_impl(self, fd, eventmask); exit: return return_value; @@ -641,7 +643,7 @@ pyepoll_modify(pyEpoll_Object *self, PyObject **args, Py_ssize_t nargs, PyObject #if defined(HAVE_EPOLL) -PyDoc_STRVAR(pyepoll_unregister__doc__, +PyDoc_STRVAR(select_epoll_unregister__doc__, "unregister($self, /, fd)\n" "--\n" "\n" @@ -650,14 +652,14 @@ PyDoc_STRVAR(pyepoll_unregister__doc__, " fd\n" " the target file descriptor of the operation"); -#define PYEPOLL_UNREGISTER_METHODDEF \ - {"unregister", (PyCFunction)pyepoll_unregister, METH_FASTCALL|METH_KEYWORDS, pyepoll_unregister__doc__}, +#define SELECT_EPOLL_UNREGISTER_METHODDEF \ + {"unregister", (PyCFunction)select_epoll_unregister, METH_FASTCALL|METH_KEYWORDS, select_epoll_unregister__doc__}, static PyObject * -pyepoll_unregister_impl(pyEpoll_Object *self, int fd); +select_epoll_unregister_impl(pyEpoll_Object *self, int fd); static PyObject * -pyepoll_unregister(pyEpoll_Object *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) +select_epoll_unregister(pyEpoll_Object *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; static const char * const _keywords[] = {"fd", NULL}; @@ -668,7 +670,7 @@ pyepoll_unregister(pyEpoll_Object *self, PyObject **args, Py_ssize_t nargs, PyOb fildes_converter, &fd)) { goto exit; } - return_value = pyepoll_unregister_impl(self, fd); + return_value = select_epoll_unregister_impl(self, fd); exit: return return_value; @@ -678,26 +680,27 @@ pyepoll_unregister(pyEpoll_Object *self, PyObject **args, Py_ssize_t nargs, PyOb #if defined(HAVE_EPOLL) -PyDoc_STRVAR(pyepoll_poll__doc__, +PyDoc_STRVAR(select_epoll_poll__doc__, "poll($self, /, timeout=-1.0, maxevents=-1)\n" "--\n" "\n" "Wait for events on the epoll file descriptor.\n" "\n" -"timeout gives the maximum time to wait in seconds (as float).\n" -"A timeout of -1 makes poll wait indefinitely.\n" -"Up to maxevents are returned to the caller.\n" -"\n" -"The return value is a list of tuples of the form (fd, events)."); +" timeout\n" +" the maximum time to wait in seconds (as float);\n" +" a timeout of -1 makes poll wait indefinitely\n" +" maxevents\n" +" the maximum number of events returned"); -#define PYEPOLL_POLL_METHODDEF \ - {"poll", (PyCFunction)pyepoll_poll, METH_FASTCALL|METH_KEYWORDS, pyepoll_poll__doc__}, +#define SELECT_EPOLL_POLL_METHODDEF \ + {"poll", (PyCFunction)select_epoll_poll, METH_FASTCALL|METH_KEYWORDS, select_epoll_poll__doc__}, static PyObject * -pyepoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj, int maxevents); +select_epoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj, + int maxevents); static PyObject * -pyepoll_poll(pyEpoll_Object *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) +select_epoll_poll(pyEpoll_Object *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; static const char * const _keywords[] = {"timeout", "maxevents", NULL}; @@ -709,7 +712,7 @@ pyepoll_poll(pyEpoll_Object *self, PyObject **args, Py_ssize_t nargs, PyObject * &timeout_obj, &maxevents)) { goto exit; } - return_value = pyepoll_poll_impl(self, timeout_obj, maxevents); + return_value = select_epoll_poll_impl(self, timeout_obj, maxevents); exit: return return_value; @@ -719,41 +722,41 @@ pyepoll_poll(pyEpoll_Object *self, PyObject **args, Py_ssize_t nargs, PyObject * #if defined(HAVE_EPOLL) -PyDoc_STRVAR(pyepoll_enter__doc__, +PyDoc_STRVAR(select_epoll___enter____doc__, "__enter__($self, /)\n" "--\n" "\n"); -#define PYEPOLL_ENTER_METHODDEF \ - {"__enter__", (PyCFunction)pyepoll_enter, METH_NOARGS, pyepoll_enter__doc__}, +#define SELECT_EPOLL___ENTER___METHODDEF \ + {"__enter__", (PyCFunction)select_epoll___enter__, METH_NOARGS, select_epoll___enter____doc__}, static PyObject * -pyepoll_enter_impl(pyEpoll_Object *self); +select_epoll___enter___impl(pyEpoll_Object *self); static PyObject * -pyepoll_enter(pyEpoll_Object *self, PyObject *Py_UNUSED(ignored)) +select_epoll___enter__(pyEpoll_Object *self, PyObject *Py_UNUSED(ignored)) { - return pyepoll_enter_impl(self); + return select_epoll___enter___impl(self); } #endif /* defined(HAVE_EPOLL) */ #if defined(HAVE_EPOLL) -PyDoc_STRVAR(pyepoll_exit__doc__, +PyDoc_STRVAR(select_epoll___exit____doc__, "__exit__($self, exc_type=None, exc_value=None, exc_tb=None, /)\n" "--\n" "\n"); -#define PYEPOLL_EXIT_METHODDEF \ - {"__exit__", (PyCFunction)pyepoll_exit, METH_FASTCALL, pyepoll_exit__doc__}, +#define SELECT_EPOLL___EXIT___METHODDEF \ + {"__exit__", (PyCFunction)select_epoll___exit__, METH_FASTCALL, select_epoll___exit____doc__}, static PyObject * -pyepoll_exit_impl(pyEpoll_Object *self, PyObject *exc_type, - PyObject *exc_value, PyObject *exc_tb); +select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type, + PyObject *exc_value, PyObject *exc_tb); static PyObject * -pyepoll_exit(pyEpoll_Object *self, PyObject **args, Py_ssize_t nargs) +select_epoll___exit__(pyEpoll_Object *self, PyObject **args, Py_ssize_t nargs) { PyObject *return_value = NULL; PyObject *exc_type = Py_None; @@ -765,7 +768,7 @@ pyepoll_exit(pyEpoll_Object *self, PyObject **args, Py_ssize_t nargs) &exc_type, &exc_value, &exc_tb)) { goto exit; } - return_value = pyepoll_exit_impl(self, exc_type, exc_value, exc_tb); + return_value = select_epoll___exit___impl(self, exc_type, exc_value, exc_tb); exit: return return_value; @@ -966,19 +969,19 @@ select_kqueue_control(kqueue_queue_Object *self, PyObject **args, Py_ssize_t nar #define SELECT_DEVPOLL_METHODDEF #endif /* !defined(SELECT_DEVPOLL_METHODDEF) */ -#ifndef PYEPOLL_FROMFD_METHODDEF - #define PYEPOLL_FROMFD_METHODDEF -#endif /* !defined(PYEPOLL_FROMFD_METHODDEF) */ +#ifndef SELECT_EPOLL_FROMFD_METHODDEF + #define SELECT_EPOLL_FROMFD_METHODDEF +#endif /* !defined(SELECT_EPOLL_FROMFD_METHODDEF) */ -#ifndef PYEPOLL_ENTER_METHODDEF - #define PYEPOLL_ENTER_METHODDEF -#endif /* !defined(PYEPOLL_ENTER_METHODDEF) */ +#ifndef SELECT_EPOLL___ENTER___METHODDEF + #define SELECT_EPOLL___ENTER___METHODDEF +#endif /* !defined(SELECT_EPOLL___ENTER___METHODDEF) */ -#ifndef PYEPOLL_EXIT_METHODDEF - #define PYEPOLL_EXIT_METHODDEF -#endif /* !defined(PYEPOLL_EXIT_METHODDEF) */ +#ifndef SELECT_EPOLL___EXIT___METHODDEF + #define SELECT_EPOLL___EXIT___METHODDEF +#endif /* !defined(SELECT_EPOLL___EXIT___METHODDEF) */ #ifndef SELECT_KQUEUE_CONTROL_METHODDEF #define SELECT_KQUEUE_CONTROL_METHODDEF #endif /* !defined(SELECT_KQUEUE_CONTROL_METHODDEF) */ -/*[clinic end generated code: output=fd52937a289a6697 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=31cb97633e7c6f24 input=a9049054013a1b77]*/ diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index c545c5da44f797..967ee3996bded1 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -1286,7 +1286,7 @@ newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd) /*[clinic input] @classmethod -select.epoll.__new__ as pyepoll_new +select.epoll.__new__ sizehint: int(c_default="FD_SETSIZE - 1") = -1 sizehint must be a positive integer or -1 for the default size. The @@ -1298,8 +1298,8 @@ Returns an epolling object. [clinic start generated code]*/ static PyObject * -pyepoll_new_impl(PyTypeObject *type, int sizehint, int flags) -/*[clinic end generated code: output=fcb34fe462324b94 input=37a75964694b6816]*/ +select_epoll_impl(PyTypeObject *type, int sizehint, int flags) +/*[clinic end generated code: output=c87404e705013bb5 input=15bd182fdfa3557c]*/ { if (sizehint < 0) { PyErr_SetString(PyExc_ValueError, "negative sizehint"); @@ -1322,7 +1322,7 @@ pyepoll_dealloc(pyEpoll_Object *self) } /*[clinic input] -select.epoll.close as pyepoll_close +select.epoll.close Close the epoll control file descriptor. @@ -1330,8 +1330,8 @@ Further operations on the epoll object will raise an exception. [clinic start generated code]*/ static PyObject * -pyepoll_close_impl(pyEpoll_Object *self) -/*[clinic end generated code: output=8a45f35c8a91003f input=8eb5514f13b41be7]*/ +select_epoll_close_impl(pyEpoll_Object *self) +/*[clinic end generated code: output=ee2144c446a1a435 input=ca6c66ba5a736bfd]*/ { errno = pyepoll_internal_close(self); if (errno < 0) { @@ -1352,14 +1352,14 @@ pyepoll_get_closed(pyEpoll_Object *self) } /*[clinic input] -select.epoll.fileno as pyepoll_fileno +select.epoll.fileno Return the epoll control file descriptor. [clinic start generated code]*/ static PyObject * -pyepoll_fileno_impl(pyEpoll_Object *self) -/*[clinic end generated code: output=fe410e728fb9d923 input=f57a7ce98e39b879]*/ +select_epoll_fileno_impl(pyEpoll_Object *self) +/*[clinic end generated code: output=e171375fdc619ba3 input=c11091a6aee60b5c]*/ { if (self->epfd < 0) return pyepoll_err_closed(); @@ -1369,7 +1369,7 @@ pyepoll_fileno_impl(pyEpoll_Object *self) /*[clinic input] @classmethod -select.epoll.fromfd as pyepoll_fromfd +select.epoll.fromfd fd: int / @@ -1378,8 +1378,8 @@ Create an epoll object from a given control fd. [clinic start generated code]*/ static PyObject * -pyepoll_fromfd_impl(PyTypeObject *type, int fd) -/*[clinic end generated code: output=d1efabee2ab54d69 input=018090223b95d685]*/ +select_epoll_fromfd_impl(PyTypeObject *type, int fd) +/*[clinic end generated code: output=c15de2a083524e8e input=faecefdb55e3046e]*/ { SOCKET s_fd = (SOCKET)fd; return newPyEpoll_Object(type, FD_SETSIZE - 1, 0, s_fd); @@ -1431,7 +1431,7 @@ pyepoll_internal_ctl(int epfd, int op, int fd, unsigned int events) } /*[clinic input] -select.epoll.register as pyepoll_register +select.epoll.register fd: fildes the target file descriptor of the operation @@ -1444,14 +1444,15 @@ The epoll interface supports all file descriptors that support poll. [clinic start generated code]*/ static PyObject * -pyepoll_register_impl(pyEpoll_Object *self, int fd, unsigned int eventmask) -/*[clinic end generated code: output=3244c166875dda1f input=a2dcd94e3b1692d6]*/ +select_epoll_register_impl(pyEpoll_Object *self, int fd, + unsigned int eventmask) +/*[clinic end generated code: output=318e5e6386520599 input=aee776f8e8d6d25f]*/ { return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, fd, eventmask); } /*[clinic input] -select.epoll.modify as pyepoll_modify +select.epoll.modify fd: fildes the target file descriptor of the operation @@ -1462,14 +1463,15 @@ Modify event mask for a registered file descriptor. [clinic start generated code]*/ static PyObject * -pyepoll_modify_impl(pyEpoll_Object *self, int fd, unsigned int eventmask) -/*[clinic end generated code: output=5d5093932bbf9234 input=17ba4cf5230fe7e1]*/ +select_epoll_modify_impl(pyEpoll_Object *self, int fd, + unsigned int eventmask) +/*[clinic end generated code: output=7e3447307cff6f65 input=88a83dac53a8c3da]*/ { return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, fd, eventmask); } /*[clinic input] -select.epoll.unregister as pyepoll_unregister +select.epoll.unregister fd: fildes the target file descriptor of the operation @@ -1478,30 +1480,28 @@ Remove a registered file descriptor from the epoll object. [clinic start generated code]*/ static PyObject * -pyepoll_unregister_impl(pyEpoll_Object *self, int fd) -/*[clinic end generated code: output=539abcb9ec95f6b8 input=35b3cebfae5cbc12]*/ +select_epoll_unregister_impl(pyEpoll_Object *self, int fd) +/*[clinic end generated code: output=07c5dbd612a512d4 input=3093f68d3644743d]*/ { return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, fd, 0); } /*[clinic input] -select.epoll.poll as pyepoll_poll +select.epoll.poll timeout as timeout_obj: object(c_default="Py_None") = -1.0 + the maximum time to wait in seconds (as float); + a timeout of -1 makes poll wait indefinitely maxevents: int = -1 + the maximum number of events returned Wait for events on the epoll file descriptor. - -timeout gives the maximum time to wait in seconds (as float). -A timeout of -1 makes poll wait indefinitely. -Up to maxevents are returned to the caller. - -The return value is a list of tuples of the form (fd, events). [clinic start generated code]*/ static PyObject * -pyepoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj, int maxevents) -/*[clinic end generated code: output=f2d43090f6f8c981 input=6896abf8945c94e6]*/ +select_epoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj, + int maxevents) +/*[clinic end generated code: output=e02d121a20246c6c input=205c0207f1971f5f]*/ { int nfds, i; PyObject *elist = NULL, *etuple = NULL; @@ -1603,13 +1603,13 @@ pyepoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj, int maxevents) /*[clinic input] -select.epoll.__enter__ as pyepoll_enter +select.epoll.__enter__ [clinic start generated code]*/ static PyObject * -pyepoll_enter_impl(pyEpoll_Object *self) -/*[clinic end generated code: output=b83429abc001fbad input=10e21534771c340a]*/ +select_epoll___enter___impl(pyEpoll_Object *self) +/*[clinic end generated code: output=ab45d433504db2a0 input=3c22568587efeadb]*/ { if (self->epfd < 0) return pyepoll_err_closed(); @@ -1619,7 +1619,7 @@ pyepoll_enter_impl(pyEpoll_Object *self) } /*[clinic input] -select.epoll.__exit__ as pyepoll_exit +select.epoll.__exit__ exc_type: object = None exc_value: object = None @@ -1629,9 +1629,9 @@ select.epoll.__exit__ as pyepoll_exit [clinic start generated code]*/ static PyObject * -pyepoll_exit_impl(pyEpoll_Object *self, PyObject *exc_type, - PyObject *exc_value, PyObject *exc_tb) -/*[clinic end generated code: output=2a9663282b522719 input=b9e36359f35eadb4]*/ +select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type, + PyObject *exc_value, PyObject *exc_tb) +/*[clinic end generated code: output=c480f38ce361748e input=7ae81a5a4c1a98d8]*/ { _Py_IDENTIFIER(close); From b91b2db21529e9dffb782fffc7660246bec8f604 Mon Sep 17 00:00:00 2001 From: Tal Einat Date: Fri, 3 Nov 2017 09:14:22 +0200 Subject: [PATCH 08/17] bpo-20182: selectmodule.c AC: fix two compilation errors in epoll --- Modules/selectmodule.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 967ee3996bded1..2bb3b2fad3b873 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -1382,7 +1382,7 @@ select_epoll_fromfd_impl(PyTypeObject *type, int fd) /*[clinic end generated code: output=c15de2a083524e8e input=faecefdb55e3046e]*/ { SOCKET s_fd = (SOCKET)fd; - return newPyEpoll_Object(type, FD_SETSIZE - 1, 0, s_fd); + return newPyEpoll_Object(type, FD_SETSIZE - 1, s_fd); } @@ -1391,7 +1391,6 @@ pyepoll_internal_ctl(int epfd, int op, int fd, unsigned int events) { struct epoll_event ev; int result; - int fd; if (epfd < 0) return pyepoll_err_closed(); From 7939e70e9953d0bc29994285f191e89984b158a6 Mon Sep 17 00:00:00 2001 From: Tal Einat Date: Fri, 3 Nov 2017 23:49:22 +0200 Subject: [PATCH 09/17] bpo-20182: selectmodule.c AC: re-run clinic.py after its recent bugfix --- Modules/clinic/selectmodule.c.h | 58 ++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/Modules/clinic/selectmodule.c.h b/Modules/clinic/selectmodule.c.h index 8949ae1762552a..753226c231558e 100644 --- a/Modules/clinic/selectmodule.c.h +++ b/Modules/clinic/selectmodule.c.h @@ -957,6 +957,22 @@ select_kqueue_control(kqueue_queue_Object *self, PyObject **args, Py_ssize_t nar #define SELECT_POLL_POLL_METHODDEF #endif /* !defined(SELECT_POLL_POLL_METHODDEF) */ +#ifndef SELECT_DEVPOLL_REGISTER_METHODDEF + #define SELECT_DEVPOLL_REGISTER_METHODDEF +#endif /* !defined(SELECT_DEVPOLL_REGISTER_METHODDEF) */ + +#ifndef SELECT_DEVPOLL_MODIFY_METHODDEF + #define SELECT_DEVPOLL_MODIFY_METHODDEF +#endif /* !defined(SELECT_DEVPOLL_MODIFY_METHODDEF) */ + +#ifndef SELECT_DEVPOLL_UNREGISTER_METHODDEF + #define SELECT_DEVPOLL_UNREGISTER_METHODDEF +#endif /* !defined(SELECT_DEVPOLL_UNREGISTER_METHODDEF) */ + +#ifndef SELECT_DEVPOLL_POLL_METHODDEF + #define SELECT_DEVPOLL_POLL_METHODDEF +#endif /* !defined(SELECT_DEVPOLL_POLL_METHODDEF) */ + #ifndef SELECT_DEVPOLL_CLOSE_METHODDEF #define SELECT_DEVPOLL_CLOSE_METHODDEF #endif /* !defined(SELECT_DEVPOLL_CLOSE_METHODDEF) */ @@ -965,14 +981,42 @@ select_kqueue_control(kqueue_queue_Object *self, PyObject **args, Py_ssize_t nar #define SELECT_DEVPOLL_FILENO_METHODDEF #endif /* !defined(SELECT_DEVPOLL_FILENO_METHODDEF) */ +#ifndef SELECT_POLL_METHODDEF + #define SELECT_POLL_METHODDEF +#endif /* !defined(SELECT_POLL_METHODDEF) */ + #ifndef SELECT_DEVPOLL_METHODDEF #define SELECT_DEVPOLL_METHODDEF #endif /* !defined(SELECT_DEVPOLL_METHODDEF) */ +#ifndef SELECT_EPOLL_CLOSE_METHODDEF + #define SELECT_EPOLL_CLOSE_METHODDEF +#endif /* !defined(SELECT_EPOLL_CLOSE_METHODDEF) */ + +#ifndef SELECT_EPOLL_FILENO_METHODDEF + #define SELECT_EPOLL_FILENO_METHODDEF +#endif /* !defined(SELECT_EPOLL_FILENO_METHODDEF) */ + #ifndef SELECT_EPOLL_FROMFD_METHODDEF #define SELECT_EPOLL_FROMFD_METHODDEF #endif /* !defined(SELECT_EPOLL_FROMFD_METHODDEF) */ +#ifndef SELECT_EPOLL_REGISTER_METHODDEF + #define SELECT_EPOLL_REGISTER_METHODDEF +#endif /* !defined(SELECT_EPOLL_REGISTER_METHODDEF) */ + +#ifndef SELECT_EPOLL_MODIFY_METHODDEF + #define SELECT_EPOLL_MODIFY_METHODDEF +#endif /* !defined(SELECT_EPOLL_MODIFY_METHODDEF) */ + +#ifndef SELECT_EPOLL_UNREGISTER_METHODDEF + #define SELECT_EPOLL_UNREGISTER_METHODDEF +#endif /* !defined(SELECT_EPOLL_UNREGISTER_METHODDEF) */ + +#ifndef SELECT_EPOLL_POLL_METHODDEF + #define SELECT_EPOLL_POLL_METHODDEF +#endif /* !defined(SELECT_EPOLL_POLL_METHODDEF) */ + #ifndef SELECT_EPOLL___ENTER___METHODDEF #define SELECT_EPOLL___ENTER___METHODDEF #endif /* !defined(SELECT_EPOLL___ENTER___METHODDEF) */ @@ -981,7 +1025,19 @@ select_kqueue_control(kqueue_queue_Object *self, PyObject **args, Py_ssize_t nar #define SELECT_EPOLL___EXIT___METHODDEF #endif /* !defined(SELECT_EPOLL___EXIT___METHODDEF) */ +#ifndef SELECT_KQUEUE_CLOSE_METHODDEF + #define SELECT_KQUEUE_CLOSE_METHODDEF +#endif /* !defined(SELECT_KQUEUE_CLOSE_METHODDEF) */ + +#ifndef SELECT_KQUEUE_FILENO_METHODDEF + #define SELECT_KQUEUE_FILENO_METHODDEF +#endif /* !defined(SELECT_KQUEUE_FILENO_METHODDEF) */ + +#ifndef SELECT_KQUEUE_FROMFD_METHODDEF + #define SELECT_KQUEUE_FROMFD_METHODDEF +#endif /* !defined(SELECT_KQUEUE_FROMFD_METHODDEF) */ + #ifndef SELECT_KQUEUE_CONTROL_METHODDEF #define SELECT_KQUEUE_CONTROL_METHODDEF #endif /* !defined(SELECT_KQUEUE_CONTROL_METHODDEF) */ -/*[clinic end generated code: output=31cb97633e7c6f24 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=24d97bdbdf346b5f input=a9049054013a1b77]*/ From 7de2e5d6658937a2eef25487a92ccc43e97f6fd8 Mon Sep 17 00:00:00 2001 From: Tal Einat Date: Fri, 22 Jun 2018 22:02:03 +0300 Subject: [PATCH 10/17] bpo-31938: address remaining CR issues --- Doc/library/select.rst | 2 +- Modules/clinic/selectmodule.c.h | 18 +++++++++--------- Modules/selectmodule.c | 30 +++++++++++++++--------------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/Doc/library/select.rst b/Doc/library/select.rst index bd5442c6a27aa0..2400f4f84c4adb 100644 --- a/Doc/library/select.rst +++ b/Doc/library/select.rst @@ -342,7 +342,7 @@ Edge and Level Trigger Polling (epoll) Objects Remove a registered file descriptor from the epoll object. -.. method:: epoll.poll(timeout=-1, maxevents=-1) +.. method:: epoll.poll(timeout=None, maxevents=-1) Wait for events. timeout in seconds (float) diff --git a/Modules/clinic/selectmodule.c.h b/Modules/clinic/selectmodule.c.h index 753226c231558e..feb16208a9dc2f 100644 --- a/Modules/clinic/selectmodule.c.h +++ b/Modules/clinic/selectmodule.c.h @@ -58,7 +58,7 @@ select_select(PyObject *module, PyObject **args, Py_ssize_t nargs) #if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) PyDoc_STRVAR(select_poll_register__doc__, -"register($self, fd, eventmask=POLLIN | POLLOUT | POLLPRI, /)\n" +"register($self, fd, eventmask=POLLIN | POLLPRI | POLLOUT, /)\n" "--\n" "\n" "Register a file descriptor with the polling object.\n" @@ -79,7 +79,7 @@ select_poll_register(pollObject *self, PyObject **args, Py_ssize_t nargs) { PyObject *return_value = NULL; int fd; - unsigned short eventmask = POLLIN | POLLOUT | POLLPRI; + unsigned short eventmask = POLLIN | POLLPRI | POLLOUT; if (!_PyArg_ParseStack(args, nargs, "O&|O&:register", fildes_converter, &fd, ushort_converter, &eventmask)) { @@ -202,7 +202,7 @@ select_poll_poll(pollObject *self, PyObject **args, Py_ssize_t nargs) #if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) PyDoc_STRVAR(select_devpoll_register__doc__, -"register($self, fd, eventmask=POLLIN | POLLOUT | POLLPRI, /)\n" +"register($self, fd, eventmask=POLLIN | POLLPRI | POLLOUT, /)\n" "--\n" "\n" "Register a file descriptor with the polling object.\n" @@ -225,7 +225,7 @@ select_devpoll_register(devpollObject *self, PyObject **args, Py_ssize_t nargs) { PyObject *return_value = NULL; int fd; - unsigned short eventmask = POLLIN | POLLOUT | POLLPRI; + unsigned short eventmask = POLLIN | POLLPRI | POLLOUT; if (!_PyArg_ParseStack(args, nargs, "O&|O&:register", fildes_converter, &fd, ushort_converter, &eventmask)) { @@ -242,7 +242,7 @@ select_devpoll_register(devpollObject *self, PyObject **args, Py_ssize_t nargs) #if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) PyDoc_STRVAR(select_devpoll_modify__doc__, -"modify($self, fd, eventmask=POLLIN | POLLOUT | POLLPRI, /)\n" +"modify($self, fd, eventmask=POLLIN | POLLPRI | POLLOUT, /)\n" "--\n" "\n" "Modify a possible already registered file descriptor.\n" @@ -265,7 +265,7 @@ select_devpoll_modify(devpollObject *self, PyObject **args, Py_ssize_t nargs) { PyObject *return_value = NULL; int fd; - unsigned short eventmask = POLLIN | POLLOUT | POLLPRI; + unsigned short eventmask = POLLIN | POLLPRI | POLLOUT; if (!_PyArg_ParseStack(args, nargs, "O&|O&:modify", fildes_converter, &fd, ushort_converter, &eventmask)) { @@ -560,7 +560,7 @@ select_epoll_fromfd(PyTypeObject *type, PyObject *arg) #if defined(HAVE_EPOLL) PyDoc_STRVAR(select_epoll_register__doc__, -"register($self, /, fd, eventmask=EPOLLIN | EPOLLOUT | EPOLLPRI)\n" +"register($self, /, fd, eventmask=EPOLLIN | EPOLLPRI | EPOLLOUT)\n" "--\n" "\n" "Registers a new fd or raises an OSError if the fd is already registered.\n" @@ -586,7 +586,7 @@ select_epoll_register(pyEpoll_Object *self, PyObject **args, Py_ssize_t nargs, P static const char * const _keywords[] = {"fd", "eventmask", NULL}; static _PyArg_Parser _parser = {"O&|I:register", _keywords, 0}; int fd; - unsigned int eventmask = EPOLLIN | EPOLLOUT | EPOLLPRI; + unsigned int eventmask = EPOLLIN | EPOLLPRI | EPOLLOUT; if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, fildes_converter, &fd, &eventmask)) { @@ -1040,4 +1040,4 @@ select_kqueue_control(kqueue_queue_Object *self, PyObject **args, Py_ssize_t nar #ifndef SELECT_KQUEUE_CONTROL_METHODDEF #define SELECT_KQUEUE_CONTROL_METHODDEF #endif /* !defined(SELECT_KQUEUE_CONTROL_METHODDEF) */ -/*[clinic end generated code: output=24d97bdbdf346b5f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b5b5f67051d1d463 input=a9049054013a1b77]*/ diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 2bb3b2fad3b873..cce41fa7458d41 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -452,7 +452,7 @@ select.poll.register fd: fildes either an integer, or an object with a fileno() method returning an int - eventmask: object(converter="ushort_converter", type="unsigned short", c_default="POLLIN | POLLOUT | POLLPRI") = POLLIN | POLLOUT | POLLPRI + eventmask: object(converter="ushort_converter", type="unsigned short", c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT an optional bitmask describing the type of events to check for / @@ -461,7 +461,7 @@ Register a file descriptor with the polling object. static PyObject * select_poll_register_impl(pollObject *self, int fd, unsigned short eventmask) -/*[clinic end generated code: output=0dc7173c800a4a65 input=e20f283a8250fb5e]*/ +/*[clinic end generated code: output=0dc7173c800a4a65 input=499d96a2836217f5]*/ { PyObject *key, *value; int err; @@ -590,7 +590,7 @@ select_poll_poll_impl(pollObject *self, PyObject *timeout_obj) _PyTime_t timeout = -1, ms = -1, deadline = 0; int async_err = 0; - if (timeout_obj != NULL && timeout_obj != Py_None) { + if (timeout_obj != Py_None) { if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj, _PyTime_ROUND_TIMEOUT) < 0) { if (PyErr_ExceptionMatches(PyExc_TypeError)) { @@ -831,7 +831,7 @@ select.devpoll.register fd: fildes either an integer, or an object with a fileno() method returning an int - eventmask: object(converter="ushort_converter", type="unsigned short", c_default="POLLIN | POLLOUT | POLLPRI") = POLLIN | POLLOUT | POLLPRI + eventmask: object(converter="ushort_converter", type="unsigned short", c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT an optional bitmask describing the type of events to check for / @@ -841,7 +841,7 @@ Register a file descriptor with the polling object. static PyObject * select_devpoll_register_impl(devpollObject *self, int fd, unsigned short eventmask) -/*[clinic end generated code: output=6e07fe8b74abba0c input=c6bed777bd69a7bc]*/ +/*[clinic end generated code: output=6e07fe8b74abba0c input=389a0785bb8feb57]*/ { return internal_devpoll_register(self, fd, eventmask, 0); } @@ -852,7 +852,7 @@ select.devpoll.modify fd: fildes either an integer, or an object with a fileno() method returning an int - eventmask: object(converter="ushort_converter", type="unsigned short", c_default="POLLIN | POLLOUT | POLLPRI") = POLLIN | POLLOUT | POLLPRI + eventmask: object(converter="ushort_converter", type="unsigned short", c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT an optional bitmask describing the type of events to check for / @@ -862,7 +862,7 @@ Modify a possible already registered file descriptor. static PyObject * select_devpoll_modify_impl(devpollObject *self, int fd, unsigned short eventmask) -/*[clinic end generated code: output=bc2e6d23aaff98b4 input=2d8e3ddaa722656c]*/ +/*[clinic end generated code: output=bc2e6d23aaff98b4 input=f0d7de3889cc55fb]*/ static PyObject * devpoll_modify(devpollObject *self, PyObject *args) { @@ -921,7 +921,7 @@ select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj) return devpoll_err_closed(); /* Check values for timeout */ - if (timeout_obj == NULL || timeout_obj == Py_None) { + if (timeout_obj == Py_None) { timeout = -1; ms = -1; } @@ -1434,7 +1434,7 @@ select.epoll.register fd: fildes the target file descriptor of the operation - eventmask: unsigned_int(c_default="EPOLLIN | EPOLLOUT | EPOLLPRI", bitwise=True) = EPOLLIN | EPOLLOUT | EPOLLPRI + eventmask: unsigned_int(c_default="EPOLLIN | EPOLLPRI | EPOLLOUT", bitwise=True) = EPOLLIN | EPOLLPRI | EPOLLOUT a bit set composed of the various EPOLL constants Registers a new fd or raises an OSError if the fd is already registered. @@ -1445,7 +1445,7 @@ The epoll interface supports all file descriptors that support poll. static PyObject * select_epoll_register_impl(pyEpoll_Object *self, int fd, unsigned int eventmask) -/*[clinic end generated code: output=318e5e6386520599 input=aee776f8e8d6d25f]*/ +/*[clinic end generated code: output=318e5e6386520599 input=6cf699c152dd8ca9]*/ { return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, fd, eventmask); } @@ -1488,11 +1488,11 @@ select_epoll_unregister_impl(pyEpoll_Object *self, int fd) /*[clinic input] select.epoll.poll - timeout as timeout_obj: object(c_default="Py_None") = -1.0 + timeout as timeout_obj: object = None the maximum time to wait in seconds (as float); - a timeout of -1 makes poll wait indefinitely + a timeout of None or -1 makes poll wait indefinitely maxevents: int = -1 - the maximum number of events returned + the maximum number of events returned; -1 means no limit Wait for events on the epoll file descriptor. [clinic start generated code]*/ @@ -2063,7 +2063,7 @@ select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist, return NULL; } - if (otimeout == Py_None || otimeout == NULL) { + if (otimeout == Py_None) { ptimeoutspec = NULL; } else { @@ -2087,7 +2087,7 @@ select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist, ptimeoutspec = &timeoutspec; } - if (changelist != NULL && changelist != Py_None) { + if (changelist != Py_None) { seq = PySequence_Fast(changelist, "changelist is not iterable"); if (seq == NULL) { return NULL; From 1173711ea35aea9a99629447d8196853e58088bd Mon Sep 17 00:00:00 2001 From: Tal Einat Date: Sun, 24 Jun 2018 13:40:05 +0300 Subject: [PATCH 11/17] bpo-31938: describe return values of devpoll.poll() and epoll.poll() --- Modules/selectmodule.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index cc88ec15721d45..366943476c6307 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -904,7 +904,7 @@ select.devpoll.poll Polls the set of registered file descriptors. Returns a list containing any descriptors that have events or errors to -report. +report, as a list of (fd, event) 2-tuples. [clinic start generated code]*/ static PyObject * @@ -1498,6 +1498,9 @@ select.epoll.poll the maximum number of events returned; -1 means no limit Wait for events on the epoll file descriptor. + +Returns a list containing any descriptors that have events to report, +as a list of (fd, events) 2-tuples. [clinic start generated code]*/ static PyObject * From 65d2f0d69b0b12928c5524bc5fad09b9a38d26e4 Mon Sep 17 00:00:00 2001 From: Tal Einat Date: Mon, 25 Jun 2018 15:21:03 +0300 Subject: [PATCH 12/17] bpo-31938: re-run clinic.py on Modules/selectmodule.c --- Modules/clinic/selectmodule.c.h | 9 ++++++--- Modules/selectmodule.c | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Modules/clinic/selectmodule.c.h b/Modules/clinic/selectmodule.c.h index 569e6c2a798719..c4a1328fb0f1b6 100644 --- a/Modules/clinic/selectmodule.c.h +++ b/Modules/clinic/selectmodule.c.h @@ -319,7 +319,7 @@ PyDoc_STRVAR(select_devpoll_poll__doc__, "Polls the set of registered file descriptors.\n" "\n" "Returns a list containing any descriptors that have events or errors to\n" -"report."); +"report, as a list of (fd, event) 2-tuples."); #define SELECT_DEVPOLL_POLL_METHODDEF \ {"poll", (PyCFunction)select_devpoll_poll, METH_FASTCALL|METH_KEYWORDS, select_devpoll_poll__doc__}, @@ -690,7 +690,10 @@ PyDoc_STRVAR(select_epoll_poll__doc__, " the maximum time to wait in seconds (as float);\n" " a timeout of None or -1 makes poll wait indefinitely\n" " maxevents\n" -" the maximum number of events returned; -1 means no limit"); +" the maximum number of events returned; -1 means no limit\n" +"\n" +"Returns a list containing any descriptors that have events to report,\n" +"as a list of (fd, events) 2-tuples."); #define SELECT_EPOLL_POLL_METHODDEF \ {"poll", (PyCFunction)select_epoll_poll, METH_FASTCALL|METH_KEYWORDS, select_epoll_poll__doc__}, @@ -1040,4 +1043,4 @@ select_kqueue_control(kqueue_queue_Object *self, PyObject *const *args, Py_ssize #ifndef SELECT_KQUEUE_CONTROL_METHODDEF #define SELECT_KQUEUE_CONTROL_METHODDEF #endif /* !defined(SELECT_KQUEUE_CONTROL_METHODDEF) */ -/*[clinic end generated code: output=317c96d0d6aadcc3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=541f8a02a606e554 input=a9049054013a1b77]*/ diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 366943476c6307..940b2a12da1687 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -909,7 +909,7 @@ report, as a list of (fd, event) 2-tuples. static PyObject * select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj) -/*[clinic end generated code: output=2654e5457cca0b3c input=fecb272f2f670025]*/ +/*[clinic end generated code: output=2654e5457cca0b3c input=546cd1fca3fb1efd]*/ { struct dvpoll dvp; PyObject *result_list = NULL, *timeout_obj = NULL; @@ -1506,7 +1506,7 @@ as a list of (fd, events) 2-tuples. static PyObject * select_epoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj, int maxevents) -/*[clinic end generated code: output=e02d121a20246c6c input=6fd19c94e3ac0b66]*/ +/*[clinic end generated code: output=e02d121a20246c6c input=33d34a5ea430fd5b]*/ { int nfds, i; PyObject *elist = NULL, *etuple = NULL; From 0b81db5723d8a5082fee98d61cc73715f2bf01c3 Mon Sep 17 00:00:00 2001 From: Tal Einat Date: Mon, 25 Jun 2018 20:54:16 +0300 Subject: [PATCH 13/17] bpo-31938: fix a bug in select_kqueue_fromfd_impl --- Modules/selectmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 940b2a12da1687..70702358b13d6c 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -2024,7 +2024,7 @@ select_kqueue_fromfd_impl(PyTypeObject *type, int fd) { SOCKET s_fd = (SOCKET)fd; - return newKqueue_Object((PyTypeObject*)cls, s_fd); + return newKqueue_Object(type, s_fd); } /*[clinic input] From d5a85168363a1d3c9af72d8a81c38d04c96f5000 Mon Sep 17 00:00:00 2001 From: Tal Einat Date: Mon, 25 Jun 2018 21:00:39 +0300 Subject: [PATCH 14/17] bpo-31938: minor doc-string formatting fix --- Modules/selectmodule.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 70702358b13d6c..4c75f2dfdbf3be 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -221,8 +221,9 @@ Wait until one or more file descriptors are ready for some kind of I/O. The first three arguments are sequences of file descriptors to be waited for: rlist -- wait until ready for reading wlist -- wait until ready for writing -xlist -- wait for an ``exceptional condition'' +xlist -- wait for an "exceptional condition" If only one kind of condition is required, pass [] for the other lists. + A file descriptor is either a socket or file object, or a small integer gotten from a fileno() method call on one of those. From cff311351f2e7bd679c7bcacf93351be0839342e Mon Sep 17 00:00:00 2001 From: Tal Einat Date: Mon, 25 Jun 2018 21:04:40 +0300 Subject: [PATCH 15/17] bpo-31938: fix select.devpoll.poll() timeout param to positional only --- Modules/selectmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 4c75f2dfdbf3be..13d23e9b4cf52d 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -899,8 +899,8 @@ select_devpoll_unregister_impl(devpollObject *self, int fd) /*[clinic input] select.devpoll.poll - timeout as timeout_obj: object = None + / Polls the set of registered file descriptors. From aa421fbf745381710956854a1b2474ac5a8dc177 Mon Sep 17 00:00:00 2001 From: Tal Einat Date: Mon, 25 Jun 2018 21:06:12 +0300 Subject: [PATCH 16/17] bpo-31938: re-run clinic.py on Modules/selectmodule.c (again) --- Modules/clinic/selectmodule.c.h | 16 ++++++++-------- Modules/selectmodule.c | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Modules/clinic/selectmodule.c.h b/Modules/clinic/selectmodule.c.h index c4a1328fb0f1b6..0b77061e13a273 100644 --- a/Modules/clinic/selectmodule.c.h +++ b/Modules/clinic/selectmodule.c.h @@ -11,8 +11,9 @@ PyDoc_STRVAR(select_select__doc__, "The first three arguments are sequences of file descriptors to be waited for:\n" "rlist -- wait until ready for reading\n" "wlist -- wait until ready for writing\n" -"xlist -- wait for an ``exceptional condition\'\'\n" +"xlist -- wait for an \"exceptional condition\"\n" "If only one kind of condition is required, pass [] for the other lists.\n" +"\n" "A file descriptor is either a socket or file object, or a small integer\n" "gotten from a fileno() method call on one of those.\n" "\n" @@ -313,7 +314,7 @@ select_devpoll_unregister(devpollObject *self, PyObject *arg) #if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) PyDoc_STRVAR(select_devpoll_poll__doc__, -"poll($self, /, timeout=None)\n" +"poll($self, timeout=None, /)\n" "--\n" "\n" "Polls the set of registered file descriptors.\n" @@ -322,20 +323,19 @@ PyDoc_STRVAR(select_devpoll_poll__doc__, "report, as a list of (fd, event) 2-tuples."); #define SELECT_DEVPOLL_POLL_METHODDEF \ - {"poll", (PyCFunction)select_devpoll_poll, METH_FASTCALL|METH_KEYWORDS, select_devpoll_poll__doc__}, + {"poll", (PyCFunction)select_devpoll_poll, METH_FASTCALL, select_devpoll_poll__doc__}, static PyObject * select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj); static PyObject * -select_devpoll_poll(devpollObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +select_devpoll_poll(devpollObject *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - static const char * const _keywords[] = {"timeout", NULL}; - static _PyArg_Parser _parser = {"|O:poll", _keywords, 0}; PyObject *timeout_obj = Py_None; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + if (!_PyArg_UnpackStack(args, nargs, "poll", + 0, 1, &timeout_obj)) { goto exit; } @@ -1043,4 +1043,4 @@ select_kqueue_control(kqueue_queue_Object *self, PyObject *const *args, Py_ssize #ifndef SELECT_KQUEUE_CONTROL_METHODDEF #define SELECT_KQUEUE_CONTROL_METHODDEF #endif /* !defined(SELECT_KQUEUE_CONTROL_METHODDEF) */ -/*[clinic end generated code: output=541f8a02a606e554 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=43925956cb05f79a input=a9049054013a1b77]*/ diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 13d23e9b4cf52d..042c80337be8e0 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -243,7 +243,7 @@ descriptors can be used. static PyObject * select_select_impl(PyObject *module, PyObject *rlist, PyObject *wlist, PyObject *xlist, PyObject *timeout_obj) -/*[clinic end generated code: output=2b3cfa824f7ae4cf input=c001a7f0663e3865]*/ +/*[clinic end generated code: output=2b3cfa824f7ae4cf input=177e72184352df25]*/ { #ifdef SELECT_USES_HEAP pylist *rfd2obj, *wfd2obj, *efd2obj; @@ -910,7 +910,7 @@ report, as a list of (fd, event) 2-tuples. static PyObject * select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj) -/*[clinic end generated code: output=2654e5457cca0b3c input=546cd1fca3fb1efd]*/ +/*[clinic end generated code: output=2654e5457cca0b3c input=fd0db698d84f0333]*/ { struct dvpoll dvp; PyObject *result_list = NULL, *timeout_obj = NULL; From 143233297c5fdfce393e978705c7e586eed054b4 Mon Sep 17 00:00:00 2001 From: Tal Einat Date: Mon, 25 Jun 2018 21:12:21 +0300 Subject: [PATCH 17/17] bpo-31938: fix broken function reference in kqueue_queue_Type --- Modules/selectmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 042c80337be8e0..9d0d8ea7278e7f 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -2452,7 +2452,7 @@ static PyTypeObject kqueue_queue_Type = { 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - select_kqueue_new, /* tp_new */ + select_kqueue, /* tp_new */ 0, /* tp_free */ };