diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2013-08-21 22:19:50 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2013-08-21 22:19:50 (GMT) |
commit | 13423c3726ac4aa42125ac49e6c5038a015fe3eb (patch) | |
tree | 6658b82985abb3f4c2a201cb2a6320dcc5391a66 /Modules/selectmodule.c | |
parent | 43f80e6c1f49c3590843d81a1b5ebbe1a2e1c62a (diff) | |
download | cpython-13423c3726ac4aa42125ac49e6c5038a015fe3eb.zip cpython-13423c3726ac4aa42125ac49e6c5038a015fe3eb.tar.gz cpython-13423c3726ac4aa42125ac49e6c5038a015fe3eb.tar.bz2 |
Close #18794: Add a fileno() method and a closed attribute to select.devpoll
objects.
Add also tests on fileno() method and closed attribute of select.epoll and select.kqueue.
Diffstat (limited to 'Modules/selectmodule.c')
-rw-r--r-- | Modules/selectmodule.c | 92 |
1 files changed, 85 insertions, 7 deletions
diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 414f05a..865725d 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -684,6 +684,13 @@ typedef struct { static PyTypeObject devpoll_Type; +static PyObject * +devpoll_err_closed(void) +{ + PyErr_SetString(PyExc_ValueError, "I/O operation on closed devpoll object"); + return NULL; +} + static int devpoll_flush(devpollObject *self) { int size, n; @@ -724,6 +731,9 @@ internal_devpoll_register(devpollObject *self, PyObject *args, int remove) PyObject *o; int fd, events = POLLIN | POLLPRI | POLLOUT; + if (self->fd_devpoll < 0) + return devpoll_err_closed(); + if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) { return NULL; } @@ -788,6 +798,9 @@ devpoll_unregister(devpollObject *self, PyObject *o) { int fd; + if (self->fd_devpoll < 0) + return devpoll_err_closed(); + fd = PyObject_AsFileDescriptor( o ); if (fd == -1) return NULL; @@ -817,6 +830,9 @@ devpoll_poll(devpollObject *self, PyObject *args) long timeout; PyObject *value, *num1, *num2; + if (self->fd_devpoll < 0) + return devpoll_err_closed(); + if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) { return NULL; } @@ -895,6 +911,45 @@ devpoll_poll(devpollObject *self, PyObject *args) return NULL; } +static PyObject* +devpoll_close(devpollObject *self) +{ + errno = devpoll_internal_close(self); + if (errno < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + 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) +{ + if (self->fd_devpoll < 0) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; +} + +static PyObject* +devpoll_fileno(devpollObject *self) +{ + 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 PyMethodDef devpoll_methods[] = { {"register", (PyCFunction)devpoll_register, METH_VARARGS, devpoll_register_doc}, @@ -904,9 +959,19 @@ static PyMethodDef devpoll_methods[] = { 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"}, + {0}, +}; + static devpollObject * newDevPollObject(void) { @@ -957,15 +1022,26 @@ newDevPollObject(void) return self; } +static int +devpoll_internal_close(pyEpoll_Object *self) +{ + int save_errno = 0; + if (self->fd_devpoll >= 0) { + int fd = self->fd_devpoll; + self->fd_devpoll = -1; + Py_BEGIN_ALLOW_THREADS + if (close(fd) < 0) + save_errno = errno; + Py_END_ALLOW_THREADS + } + return save_errno; +} + static void devpoll_dealloc(devpollObject *self) { - Py_BEGIN_ALLOW_THREADS - close(self->fd_devpoll); - Py_END_ALLOW_THREADS - + (void)devpoll_internal_close(); PyMem_DEL(self->fds); - PyObject_Del(self); } @@ -1001,6 +1077,8 @@ static PyTypeObject devpoll_Type = { 0, /*tp_iter*/ 0, /*tp_iternext*/ devpoll_methods, /*tp_methods*/ + 0, /* tp_members */ + devpoll_getsetlist, /* tp_getset */ }; #endif /* HAVE_SYS_DEVPOLL_H */ @@ -1084,7 +1162,7 @@ static PyTypeObject pyEpoll_Type; static PyObject * pyepoll_err_closed(void) { - PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd"); + PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll object"); return NULL; } @@ -1776,7 +1854,7 @@ static PyTypeObject kqueue_event_Type = { static PyObject * kqueue_queue_err_closed(void) { - PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd"); + PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object"); return NULL; } |