diff -r 5c0247a6f98a Lib/test/test_epoll.py --- a/Lib/test/test_epoll.py Fri Apr 24 12:02:53 2015 -0400 +++ b/Lib/test/test_epoll.py Sat Apr 25 01:25:00 2015 +0300 @@ -246,6 +246,10 @@ self.assertRaises(ValueError, epoll.register, fd, select.EPOLLIN) self.assertRaises(ValueError, epoll.unregister, fd) + # even when closed, epoll.poll() should still raise a TypeError if + # called with invalid arguments + self.assertRaises(TypeError, epoll.poll, "a", "b") + def test_fd_non_inheritable(self): epoll = select.epoll() self.addCleanup(epoll.close) diff -r 5c0247a6f98a Modules/clinic/selectmodule.c.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modules/clinic/selectmodule.c.h Sat Apr 25 01:25:00 2015 +0300 @@ -0,0 +1,590 @@ +/*[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(select_epoll__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 * +select_epoll_impl(PyTypeObject *type, int sizehint, int flags); + +static PyObject * +select_epoll(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 = select_epoll_impl(type, sizehint, flags); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(select_epoll_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 SELECT_EPOLL_CLOSE_METHODDEF \ + {"close", (PyCFunction)select_epoll_close, METH_NOARGS, select_epoll_close__doc__}, + +static PyObject * +select_epoll_close_impl(pyEpoll_Object *self); + +static PyObject * +select_epoll_close(pyEpoll_Object *self, PyObject *Py_UNUSED(ignored)) +{ + return select_epoll_close_impl(self); +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(select_epoll_fileno__doc__, +"fileno($self, /)\n" +"--\n" +"\n" +"Return the epoll control file descriptor."); + +#define SELECT_EPOLL_FILENO_METHODDEF \ + {"fileno", (PyCFunction)select_epoll_fileno, METH_NOARGS, select_epoll_fileno__doc__}, + +static PyObject * +select_epoll_fileno_impl(pyEpoll_Object *self); + +static PyObject * +select_epoll_fileno(pyEpoll_Object *self, PyObject *Py_UNUSED(ignored)) +{ + return select_epoll_fileno_impl(self); +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(select_epoll_fromfd__doc__, +"fromfd($type, fd, /)\n" +"--\n" +"\n" +"Create an epoll object from a given control fd."); + +#define SELECT_EPOLL_FROMFD_METHODDEF \ + {"fromfd", (PyCFunction)select_epoll_fromfd, METH_O|METH_CLASS, select_epoll_fromfd__doc__}, + +static PyObject * +select_epoll_fromfd_impl(PyTypeObject *type, int fd); + +static PyObject * +select_epoll_fromfd(PyTypeObject *type, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + + if (!PyArg_Parse(arg, "i:fromfd", &fd)) + goto exit; + return_value = select_epoll_fromfd_impl(type, fd); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(select_epoll_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 SELECT_EPOLL_REGISTER_METHODDEF \ + {"register", (PyCFunction)select_epoll_register, METH_VARARGS|METH_KEYWORDS, select_epoll_register__doc__}, + +static PyObject * +select_epoll_register_impl(pyEpoll_Object *self, PyObject *fd, + unsigned int eventmask); + +static PyObject * +select_epoll_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 = select_epoll_register_impl(self, fd, eventmask); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(select_epoll_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 SELECT_EPOLL_MODIFY_METHODDEF \ + {"modify", (PyCFunction)select_epoll_modify, METH_VARARGS|METH_KEYWORDS, select_epoll_modify__doc__}, + +static PyObject * +select_epoll_modify_impl(pyEpoll_Object *self, PyObject *fd, + unsigned int eventmask); + +static PyObject * +select_epoll_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 = select_epoll_modify_impl(self, fd, eventmask); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(select_epoll_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 SELECT_EPOLL_UNREGISTER_METHODDEF \ + {"unregister", (PyCFunction)select_epoll_unregister, METH_VARARGS|METH_KEYWORDS, select_epoll_unregister__doc__}, + +static PyObject * +select_epoll_unregister_impl(pyEpoll_Object *self, PyObject *fd); + +static PyObject * +select_epoll_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 = select_epoll_unregister_impl(self, fd); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +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)."); + +#define SELECT_EPOLL_POLL_METHODDEF \ + {"poll", (PyCFunction)select_epoll_poll, METH_VARARGS|METH_KEYWORDS, select_epoll_poll__doc__}, + +static PyObject * +select_epoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj, + int maxevents); + +static PyObject * +select_epoll_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 = select_epoll_poll_impl(self, timeout_obj, maxevents); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(select_epoll___enter____doc__, +"__enter__($self, /)\n" +"--\n" +"\n"); + +#define SELECT_EPOLL___ENTER___METHODDEF \ + {"__enter__", (PyCFunction)select_epoll___enter__, METH_NOARGS, select_epoll___enter____doc__}, + +static PyObject * +select_epoll___enter___impl(pyEpoll_Object *self); + +static PyObject * +select_epoll___enter__(pyEpoll_Object *self, PyObject *Py_UNUSED(ignored)) +{ + return select_epoll___enter___impl(self); +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(select_epoll___exit____doc__, +"__exit__($self, exc_type=None, exc_value=None, exc_tb=None, /)\n" +"--\n" +"\n"); + +#define SELECT_EPOLL___EXIT___METHODDEF \ + {"__exit__", (PyCFunction)select_epoll___exit__, METH_VARARGS, select_epoll___exit____doc__}, + +static PyObject * +select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type, + PyObject *exc_value, PyObject *exc_tb); + +static PyObject * +select_epoll___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 = select_epoll___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 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___ENTER___METHODDEF + #define SELECT_EPOLL___ENTER___METHODDEF +#endif /* !defined(SELECT_EPOLL___ENTER___METHODDEF) */ + +#ifndef SELECT_EPOLL___EXIT___METHODDEF + #define SELECT_EPOLL___EXIT___METHODDEF +#endif /* !defined(SELECT_EPOLL___EXIT___METHODDEF) */ +/*[clinic end generated code: output=f9d3eb6882ab60fd input=a9049054013a1b77]*/ diff -r 5c0247a6f98a Modules/selectmodule.c --- a/Modules/selectmodule.c Fri Apr 24 12:02:53 2015 -0400 +++ b/Modules/selectmodule.c Sat Apr 25 01:25:00 2015 +0300 @@ -11,7 +11,7 @@ #include #include #include -#include +#include f #include #endif @@ -38,6 +38,10 @@ #include #endif +#ifdef HAVE_SYS_EPOLL_H +#include +#endif + #ifdef __sgi /* This is missing from unistd.h */ extern void bzero(void *, int); @@ -54,6 +58,74 @@ # define SOCKET int #endif + +static int +ushort_converter(PyObject *obj, void *ptr) +{ + unsigned long uval; + + uval = PyLong_AsUnsignedLong(obj); + if (uval == (unsigned long)-1 && PyErr_Occurred()) + return 0; + if (uval > USHRT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "Python int too large for C unsigned short"); + return 0; + } + + *(unsigned short *)ptr = Py_SAFE_DOWNCAST(uval, unsigned long, unsigned short); + return 1; +} + +#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL) +/* + * poll() support + */ + +typedef struct { + PyObject_HEAD + PyObject *dict; + int ufd_uptodate; + int ufd_len; + struct pollfd *ufds; + int poll_running; +} pollObject; + +static PyTypeObject poll_Type; + +#ifdef HAVE_SYS_DEVPOLL_H +typedef struct { + PyObject_HEAD + int fd_devpoll; + int max_n_fds; + int n_fds; + struct pollfd *fds; +} devpollObject; + +static PyTypeObject devpoll_Type; +#endif /* HAVE_SYS_DEVPOLL_H */ + +#endif /* HAVE_POLL */ + +#ifdef HAVE_EPOLL +typedef struct { + PyObject_HEAD + SOCKET epfd; /* epoll control file descriptor */ +} pyEpoll_Object; + +static PyTypeObject pyEpoll_Type; +#endif /* HAVE_EPOLL */ + +#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 */ @@ -175,8 +247,42 @@ #define SELECT_USES_HEAP #endif /* FD_SETSIZE > 1024 */ +/*[clinic input] +select.select + + rlist: 'O' + wlist: 'O' + xlist: 'O' + timeout as timeout_obj: 'O' = 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; @@ -191,20 +297,13 @@ 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 { @@ -245,11 +344,11 @@ 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; @@ -297,17 +396,17 @@ 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); - - Py_XDECREF(ifdlist); - Py_XDECREF(ofdlist); - Py_XDECREF(efdlist); + ret = PyTuple_Pack(3, rlist, wlist, xlist); + + Py_XDECREF(rlist); + Py_XDECREF(wlist); + Py_XDECREF(xlist); } finally: @@ -327,17 +426,6 @@ * poll() support */ -typedef struct { - PyObject_HEAD - PyObject *dict; - int ufd_uptodate; - int ufd_len; - struct pollfd *ufds; - int poll_running; -} pollObject; - -static PyTypeObject poll_Type; - /* Update the malloc'ed array of pollfds to match the dictionary contained within a pollObject. Return 1 on success, 0 on an error. */ @@ -370,51 +458,38 @@ return 1; } -static int -ushort_converter(PyObject *obj, void *ptr) +/*[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 * +select_poll_register_impl(pollObject *self, PyObject *fd, + unsigned short eventmask) +/*[clinic end generated code: output=9d124fac4c62aa77 input=31fa73ae25f7179d]*/ { - unsigned long uval; - - uval = PyLong_AsUnsignedLong(obj); - if (uval == (unsigned long)-1 && PyErr_Occurred()) - return 0; - if (uval > USHRT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "Python int too large for C unsigned short"); - return 0; - } - - *(unsigned short *)ptr = Py_SAFE_DOWNCAST(uval, unsigned long, unsigned short); - 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"); - -static PyObject * -poll_register(pollObject *self, PyObject *args) -{ - 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; @@ -431,29 +506,34 @@ return Py_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) { @@ -462,7 +542,7 @@ Py_DECREF(key); return NULL; } - value = PyLong_FromLong(events); + value = PyLong_FromLong(eventmask); if (value == NULL) { Py_DECREF(key); return NULL; @@ -480,22 +560,28 @@ } -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: 'O' + / + +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; - - fd = PyObject_AsFileDescriptor( o ); - if (fd == -1) + 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(fd); + key = PyLong_FromLong(real_fd); if (key == NULL) return NULL; @@ -513,24 +599,28 @@ return Py_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. + +Return value is a list containing any descriptors that have events +or errors to report, in the form of tuples (fd, event). +[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, ms, deadline; int async_err = 0; - if (!PyArg_ParseTuple(args, "|O:poll", &timeout_obj)) { - return NULL; - } - /* Check values for timeout */ if (timeout_obj == NULL || timeout_obj == Py_None) { timeout = -1; @@ -654,15 +744,11 @@ } 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 * @@ -729,15 +815,6 @@ }; #ifdef HAVE_SYS_DEVPOLL_H -typedef struct { - PyObject_HEAD - int fd_devpoll; - int max_n_fds; - int n_fds; - struct pollfd *fds; -} devpollObject; - -static PyTypeObject devpoll_Type; static PyObject * devpoll_err_closed(void) @@ -1149,24 +1226,36 @@ #endif /* HAVE_SYS_DEVPOLL_H */ - -PyDoc_STRVAR(poll_doc, -"Returns a polling object, which supports registering and\n\ -unregistering file descriptors, and then polling them for I/O events."); +/*[clinic input] +select.poll + +Returns a polling object. + +The object 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 using /dev/poll. + +The object 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(); } @@ -1213,16 +1302,6 @@ * Inspired by Twisted's _epoll.pyx and select.poll() */ -#ifdef HAVE_SYS_EPOLL_H -#include -#endif - -typedef struct { - PyObject_HEAD - SOCKET epfd; /* epoll control file descriptor */ -} pyEpoll_Object; - -static PyTypeObject pyEpoll_Type; #define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type)) static PyObject * @@ -1288,15 +1367,24 @@ } +/*[clinic input] +@classmethod +select.epoll.__new__ + + sizehint: int(c_default="FD_SETSIZE - 1") = -1 + flags: int = 0 + +Returns an epolling object. + +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. +[clinic start generated code]*/ + static PyObject * -pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +select_epoll_impl(PyTypeObject *type, int sizehint, int flags) +/*[clinic end generated code: output=c87404e705013bb5 input=1a9f39a17c759de2]*/ { - 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; @@ -1313,8 +1401,17 @@ Py_TYPE(self)->tp_free(self); } -static PyObject* -pyepoll_close(pyEpoll_Object *self) +/*[clinic input] +select.epoll.close + +Close the epoll control file descriptor. + +Further operations on the epoll object will raise an exception. +[clinic start generated code]*/ + +static PyObject * +select_epoll_close_impl(pyEpoll_Object *self) +/*[clinic end generated code: output=ee2144c446a1a435 input=ca6c66ba5a736bfd]*/ { errno = pyepoll_internal_close(self); if (errno < 0) { @@ -1324,11 +1421,6 @@ 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) @@ -1339,34 +1431,40 @@ Py_RETURN_FALSE; } -static PyObject* -pyepoll_fileno(pyEpoll_Object *self) +/*[clinic input] +select.epoll.fileno + +Return the epoll control file descriptor. +[clinic start generated code]*/ + +static PyObject * +select_epoll_fileno_impl(pyEpoll_Object *self) +/*[clinic end generated code: output=e171375fdc619ba3 input=c11091a6aee60b5c]*/ { 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) + +/*[clinic input] +@classmethod +select.epoll.fromfd + + fd: 'i' + / + +Create an epoll object from a given control fd. +[clinic start generated code]*/ + +static PyObject * +select_epoll_fromfd_impl(PyTypeObject *type, int fd) +/*[clinic end generated code: output=c15de2a083524e8e input=75d53e45a3fa18d4]*/ { - SOCKET fd; - - if (!PyArg_ParseTuple(args, "i:fromfd", &fd)) - return NULL; - - return newPyEpoll_Object((PyTypeObject*)cls, FD_SETSIZE - 1, 0, fd); + 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) @@ -1417,77 +1515,88 @@ Py_RETURN_NONE; } +/* XXX wrong default below */ + +/*[clinic input] +select.epoll.register + + fd: object + eventmask: unsigned_int(c_default="EPOLLIN | EPOLLOUT | EPOLLPRI", bitwise=True) = select.EPOLLIN | select.EPOLLOUT | select.EPOLLPRI + +Registers a new fd or raises an OSError if the fd is already registered. + +fd is the target file descriptor of the operation. +events is a bit set composed of the various EPOLL constants; the default +is EPOLLIN | EPOLLOUT | EPOLLPRI. + +The epoll interface supports all file descriptors that support poll. +[clinic start generated code]*/ + static PyObject * -pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds) +select_epoll_register_impl(pyEpoll_Object *self, PyObject *fd, + unsigned int eventmask) +/*[clinic end generated code: output=c550bf2f41e2c9ff input=6e962bde7e0fa02e]*/ { - PyObject *pfd; - unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI; - static char *kwlist[] = {"fd", "eventmask", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist, - &pfd, &events)) { - return NULL; - } - - return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events); + return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, fd, eventmask); } -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 EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\ -\n\ -The epoll interface supports all file descriptors that support poll."); +/*[clinic input] +select.epoll.modify + + fd: object + eventmask: unsigned_int(bitwise=True) + +Modify event mask for a registered file descriptor. + +fd is the target file descriptor of the operation, and +events is a bit set composed of the various EPOLL constants. +[clinic start generated code]*/ static PyObject * -pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds) +select_epoll_modify_impl(pyEpoll_Object *self, PyObject *fd, + unsigned int eventmask) +/*[clinic end generated code: output=0ee1fc250a286b9d input=09537c2609ea55a2]*/ { - PyObject *pfd; - unsigned int events; - static char *kwlist[] = {"fd", "eventmask", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist, - &pfd, &events)) { - return NULL; - } - - return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events); + 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 + + fd: object + +Remove a registered file descriptor from the epoll object. + +fd is the target file descriptor of the operation. +[clinic start generated code]*/ static PyObject * -pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds) +select_epoll_unregister_impl(pyEpoll_Object *self, PyObject *fd) +/*[clinic end generated code: output=91b02d6591ac7155 input=41a43339265168d8]*/ { - PyObject *pfd; - static char *kwlist[] = {"fd", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist, - &pfd)) { - return NULL; - } - - return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0); + return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, fd, 0); } -PyDoc_STRVAR(pyepoll_unregister_doc, -"unregister(fd) -> None\n\ -\n\ -fd is the target file descriptor of the operation."); +/*[clinic input] +select.epoll.poll + + timeout as timeout_obj: object(c_default="Py_None") = -1.0 + maxevents: int = -1 + +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) +select_epoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj, + int maxevents) +/*[clinic end generated code: output=e02d121a20246c6c input=e554395dc71def93]*/ { - 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; @@ -1496,12 +1605,7 @@ 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 */ @@ -1586,20 +1690,20 @@ PyList_SET_ITEM(elist, i, etuple); } - error: + error: PyMem_Free(evs); 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__ + +[clinic start generated code]*/ static PyObject * -pyepoll_enter(pyEpoll_Object *self, PyObject *args) +select_epoll___enter___impl(pyEpoll_Object *self) +/*[clinic end generated code: output=ab45d433504db2a0 input=3c22568587efeadb]*/ { if (self->epfd < 0) return pyepoll_err_closed(); @@ -1608,33 +1712,36 @@ return (PyObject *)self; } +/*[clinic input] +select.epoll.__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) +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); - 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}, }; @@ -1644,14 +1751,6 @@ {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) @@ -1674,7 +1773,7 @@ 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 */ @@ -1691,7 +1790,7 @@ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - pyepoll_new, /* tp_new */ + select_epoll, /* tp_new */ 0, /* tp_free */ }; @@ -2342,38 +2441,11 @@ /* ************************************************************************ */ -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 */ };