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 */
};