Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(128409)

Side by Side Diff: Modules/selectmodule.c

Issue 18794: select.devpoll objects have no close() method
Patch Set: Created 6 years, 3 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« Lib/test/test_epoll.py ('K') | « Lib/test/test_kqueue.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* select - Module containing unix select(2) call. 1 /* select - Module containing unix select(2) call.
2 Under Unix, the file descriptors are small integers. 2 Under Unix, the file descriptors are small integers.
3 Under Win32, select only exists for sockets, and sockets may 3 Under Win32, select only exists for sockets, and sockets may
4 have any value except INVALID_SOCKET. 4 have any value except INVALID_SOCKET.
5 */ 5 */
6 6
7 #include "Python.h" 7 #include "Python.h"
8 #include <structmember.h> 8 #include <structmember.h>
9 9
10 #ifdef HAVE_SYS_DEVPOLL_H 10 #ifdef HAVE_SYS_DEVPOLL_H
(...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 #ifdef HAVE_SYS_DEVPOLL_H 676 #ifdef HAVE_SYS_DEVPOLL_H
677 typedef struct { 677 typedef struct {
678 PyObject_HEAD 678 PyObject_HEAD
679 int fd_devpoll; 679 int fd_devpoll;
680 int max_n_fds; 680 int max_n_fds;
681 int n_fds; 681 int n_fds;
682 struct pollfd *fds; 682 struct pollfd *fds;
683 } devpollObject; 683 } devpollObject;
684 684
685 static PyTypeObject devpoll_Type; 685 static PyTypeObject devpoll_Type;
686
687 static PyObject *
688 devpoll_err_closed(void)
689 {
690 PyErr_SetString(PyExc_ValueError, "I/O operation on closed devpoll object");
691 return NULL;
692 }
686 693
687 static int devpoll_flush(devpollObject *self) 694 static int devpoll_flush(devpollObject *self)
688 { 695 {
689 int size, n; 696 int size, n;
690 697
691 if (!self->n_fds) return 0; 698 if (!self->n_fds) return 0;
692 699
693 size = sizeof(struct pollfd)*self->n_fds; 700 size = sizeof(struct pollfd)*self->n_fds;
694 self->n_fds = 0; 701 self->n_fds = 0;
695 702
(...skipping 20 matching lines...) Expand all
716 return -1; 723 return -1;
717 } 724 }
718 return 0; 725 return 0;
719 } 726 }
720 727
721 static PyObject * 728 static PyObject *
722 internal_devpoll_register(devpollObject *self, PyObject *args, int remove) 729 internal_devpoll_register(devpollObject *self, PyObject *args, int remove)
723 { 730 {
724 PyObject *o; 731 PyObject *o;
725 int fd, events = POLLIN | POLLPRI | POLLOUT; 732 int fd, events = POLLIN | POLLPRI | POLLOUT;
733
734 if (self->fd_devpoll < 0)
735 return devpoll_err_closed();
726 736
727 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) { 737 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
728 return NULL; 738 return NULL;
729 } 739 }
730 740
731 fd = PyObject_AsFileDescriptor(o); 741 fd = PyObject_AsFileDescriptor(o);
732 if (fd == -1) return NULL; 742 if (fd == -1) return NULL;
733 743
734 if (remove) { 744 if (remove) {
735 self->fds[self->n_fds].fd = fd; 745 self->fds[self->n_fds].fd = fd;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
780 790
781 791
782 PyDoc_STRVAR(devpoll_unregister_doc, 792 PyDoc_STRVAR(devpoll_unregister_doc,
783 "unregister(fd) -> None\n\n\ 793 "unregister(fd) -> None\n\n\
784 Remove a file descriptor being tracked by the polling object."); 794 Remove a file descriptor being tracked by the polling object.");
785 795
786 static PyObject * 796 static PyObject *
787 devpoll_unregister(devpollObject *self, PyObject *o) 797 devpoll_unregister(devpollObject *self, PyObject *o)
788 { 798 {
789 int fd; 799 int fd;
800
801 if (self->fd_devpoll < 0)
802 return devpoll_err_closed();
790 803
791 fd = PyObject_AsFileDescriptor( o ); 804 fd = PyObject_AsFileDescriptor( o );
792 if (fd == -1) 805 if (fd == -1)
793 return NULL; 806 return NULL;
794 807
795 self->fds[self->n_fds].fd = fd; 808 self->fds[self->n_fds].fd = fd;
796 self->fds[self->n_fds].events = POLLREMOVE; 809 self->fds[self->n_fds].events = POLLREMOVE;
797 810
798 if (++self->n_fds == self->max_n_fds) { 811 if (++self->n_fds == self->max_n_fds) {
799 if (devpoll_flush(self)) 812 if (devpoll_flush(self))
800 return NULL; 813 return NULL;
801 } 814 }
802 815
803 Py_RETURN_NONE; 816 Py_RETURN_NONE;
804 } 817 }
805 818
806 PyDoc_STRVAR(devpoll_poll_doc, 819 PyDoc_STRVAR(devpoll_poll_doc,
807 "poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\ 820 "poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
808 Polls the set of registered file descriptors, returning a list containing \n\ 821 Polls the set of registered file descriptors, returning a list containing \n\
809 any descriptors that have events or errors to report."); 822 any descriptors that have events or errors to report.");
810 823
811 static PyObject * 824 static PyObject *
812 devpoll_poll(devpollObject *self, PyObject *args) 825 devpoll_poll(devpollObject *self, PyObject *args)
813 { 826 {
814 struct dvpoll dvp; 827 struct dvpoll dvp;
815 PyObject *result_list = NULL, *tout = NULL; 828 PyObject *result_list = NULL, *tout = NULL;
816 int poll_result, i; 829 int poll_result, i;
817 long timeout; 830 long timeout;
818 PyObject *value, *num1, *num2; 831 PyObject *value, *num1, *num2;
832
833 if (self->fd_devpoll < 0)
834 return devpoll_err_closed();
819 835
820 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) { 836 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
821 return NULL; 837 return NULL;
822 } 838 }
823 839
824 /* Check values for timeout */ 840 /* Check values for timeout */
825 if (tout == NULL || tout == Py_None) 841 if (tout == NULL || tout == Py_None)
826 timeout = -1; 842 timeout = -1;
827 else if (!PyNumber_Check(tout)) { 843 else if (!PyNumber_Check(tout)) {
828 PyErr_SetString(PyExc_TypeError, 844 PyErr_SetString(PyExc_TypeError,
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
887 } 903 }
888 } 904 }
889 } 905 }
890 906
891 return result_list; 907 return result_list;
892 908
893 error: 909 error:
894 Py_DECREF(result_list); 910 Py_DECREF(result_list);
895 return NULL; 911 return NULL;
896 } 912 }
913
914 static PyObject*
915 devpoll_close(devpollObject *self)
916 {
917 errno = devpoll_internal_close(self);
918 if (errno < 0) {
919 PyErr_SetFromErrno(PyExc_OSError);
920 return NULL;
921 }
922 Py_RETURN_NONE;
923 }
924
925 PyDoc_STRVAR(devpoll_close_doc,
926 "close() -> None\n\
927 \n\
928 Close the devpoll control file descriptor. Further operations on the devpoll\n\
929 object will raise an exception.");
930
931 static PyObject*
932 devpoll_get_closed(devpollObject *self)
933 {
934 if (self->fd_devpoll < 0)
935 Py_RETURN_TRUE;
936 else
937 Py_RETURN_FALSE;
938 }
939
940 static PyObject*
941 devpoll_fileno(devpollObject *self)
942 {
943 if (self->fd_devpoll < 0)
944 return devpoll_err_closed();
945 return PyLong_FromLong(self->fd_devpoll);
946 }
947
948 PyDoc_STRVAR(devpoll_fileno_doc,
949 "fileno() -> int\n\
950 \n\
951 Return the file descriptor.");
897 952
898 static PyMethodDef devpoll_methods[] = { 953 static PyMethodDef devpoll_methods[] = {
899 {"register", (PyCFunction)devpoll_register, 954 {"register", (PyCFunction)devpoll_register,
900 METH_VARARGS, devpoll_register_doc}, 955 METH_VARARGS, devpoll_register_doc},
901 {"modify", (PyCFunction)devpoll_modify, 956 {"modify", (PyCFunction)devpoll_modify,
902 METH_VARARGS, devpoll_modify_doc}, 957 METH_VARARGS, devpoll_modify_doc},
903 {"unregister", (PyCFunction)devpoll_unregister, 958 {"unregister", (PyCFunction)devpoll_unregister,
904 METH_O, devpoll_unregister_doc}, 959 METH_O, devpoll_unregister_doc},
905 {"poll", (PyCFunction)devpoll_poll, 960 {"poll", (PyCFunction)devpoll_poll,
906 METH_VARARGS, devpoll_poll_doc}, 961 METH_VARARGS, devpoll_poll_doc},
962 {"close", (PyCFunction)devpoll_close, METH_NOARGS,
963 devpoll_close_doc},
964 {"fileno", (PyCFunction)devpoll_fileno, METH_NOARGS,
965 devpoll_fileno_doc},
907 {NULL, NULL} /* sentinel */ 966 {NULL, NULL} /* sentinel */
967 };
968
969 static PyGetSetDef devpoll_getsetlist[] = {
970 {"closed", (getter)devpoll_get_closed, NULL,
971 "True if the devpoll handler is closed"},
972 {0},
908 }; 973 };
909 974
910 static devpollObject * 975 static devpollObject *
911 newDevPollObject(void) 976 newDevPollObject(void)
912 { 977 {
913 devpollObject *self; 978 devpollObject *self;
914 int fd_devpoll, limit_result; 979 int fd_devpoll, limit_result;
915 struct pollfd *fds; 980 struct pollfd *fds;
916 struct rlimit limit; 981 struct rlimit limit;
917 982
(...skipping 30 matching lines...) Expand all
948 close(fd_devpoll); 1013 close(fd_devpoll);
949 PyMem_DEL(fds); 1014 PyMem_DEL(fds);
950 return NULL; 1015 return NULL;
951 } 1016 }
952 self->fd_devpoll = fd_devpoll; 1017 self->fd_devpoll = fd_devpoll;
953 self->max_n_fds = limit.rlim_cur; 1018 self->max_n_fds = limit.rlim_cur;
954 self->n_fds = 0; 1019 self->n_fds = 0;
955 self->fds = fds; 1020 self->fds = fds;
956 1021
957 return self; 1022 return self;
1023 }
1024
1025 static int
1026 devpoll_internal_close(pyEpoll_Object *self)
1027 {
1028 int save_errno = 0;
1029 if (self->fd_devpoll >= 0) {
1030 int fd = self->fd_devpoll;
1031 self->fd_devpoll = -1;
1032 Py_BEGIN_ALLOW_THREADS
1033 if (close(fd) < 0)
1034 save_errno = errno;
1035 Py_END_ALLOW_THREADS
1036 }
1037 return save_errno;
958 } 1038 }
959 1039
960 static void 1040 static void
961 devpoll_dealloc(devpollObject *self) 1041 devpoll_dealloc(devpollObject *self)
962 { 1042 {
963 Py_BEGIN_ALLOW_THREADS 1043 (void)devpoll_internal_close();
964 close(self->fd_devpoll);
965 Py_END_ALLOW_THREADS
966
967 PyMem_DEL(self->fds); 1044 PyMem_DEL(self->fds);
968
969 PyObject_Del(self); 1045 PyObject_Del(self);
970 } 1046 }
971 1047
972 static PyTypeObject devpoll_Type = { 1048 static PyTypeObject devpoll_Type = {
973 /* The ob_type field must be initialized in the module init function 1049 /* The ob_type field must be initialized in the module init function
974 * to be portable to Windows without using C++. */ 1050 * to be portable to Windows without using C++. */
975 PyVarObject_HEAD_INIT(NULL, 0) 1051 PyVarObject_HEAD_INIT(NULL, 0)
976 "select.devpoll", /*tp_name*/ 1052 "select.devpoll", /*tp_name*/
977 sizeof(devpollObject), /*tp_basicsize*/ 1053 sizeof(devpollObject), /*tp_basicsize*/
978 0, /*tp_itemsize*/ 1054 0, /*tp_itemsize*/
(...skipping 15 matching lines...) Expand all
994 0, /*tp_as_buffer*/ 1070 0, /*tp_as_buffer*/
995 Py_TPFLAGS_DEFAULT, /*tp_flags*/ 1071 Py_TPFLAGS_DEFAULT, /*tp_flags*/
996 0, /*tp_doc*/ 1072 0, /*tp_doc*/
997 0, /*tp_traverse*/ 1073 0, /*tp_traverse*/
998 0, /*tp_clear*/ 1074 0, /*tp_clear*/
999 0, /*tp_richcompare*/ 1075 0, /*tp_richcompare*/
1000 0, /*tp_weaklistoffset*/ 1076 0, /*tp_weaklistoffset*/
1001 0, /*tp_iter*/ 1077 0, /*tp_iter*/
1002 0, /*tp_iternext*/ 1078 0, /*tp_iternext*/
1003 devpoll_methods, /*tp_methods*/ 1079 devpoll_methods, /*tp_methods*/
1080 0, /* tp_members */
1081 devpoll_getsetlist, /* tp_getset */
1004 }; 1082 };
1005 #endif /* HAVE_SYS_DEVPOLL_H */ 1083 #endif /* HAVE_SYS_DEVPOLL_H */
1006 1084
1007 1085
1008 1086
1009 PyDoc_STRVAR(poll_doc, 1087 PyDoc_STRVAR(poll_doc,
1010 "Returns a polling object, which supports registering and\n\ 1088 "Returns a polling object, which supports registering and\n\
1011 unregistering file descriptors, and then polling them for I/O events."); 1089 unregistering file descriptors, and then polling them for I/O events.");
1012 1090
1013 static PyObject * 1091 static PyObject *
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1077 PyObject_HEAD 1155 PyObject_HEAD
1078 SOCKET epfd; /* epoll control file descriptor */ 1156 SOCKET epfd; /* epoll control file descriptor */
1079 } pyEpoll_Object; 1157 } pyEpoll_Object;
1080 1158
1081 static PyTypeObject pyEpoll_Type; 1159 static PyTypeObject pyEpoll_Type;
1082 #define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type)) 1160 #define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
1083 1161
1084 static PyObject * 1162 static PyObject *
1085 pyepoll_err_closed(void) 1163 pyepoll_err_closed(void)
1086 { 1164 {
1087 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd"); 1165 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll object");
1088 return NULL; 1166 return NULL;
1089 } 1167 }
1090 1168
1091 static int 1169 static int
1092 pyepoll_internal_close(pyEpoll_Object *self) 1170 pyepoll_internal_close(pyEpoll_Object *self)
1093 { 1171 {
1094 int save_errno = 0; 1172 int save_errno = 0;
1095 if (self->epfd >= 0) { 1173 if (self->epfd >= 0) {
1096 int epfd = self->epfd; 1174 int epfd = self->epfd;
1097 self->epfd = -1; 1175 self->epfd = -1;
(...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after
1769 0, /* tp_dictoffset */ 1847 0, /* tp_dictoffset */
1770 (initproc)kqueue_event_init, /* tp_init */ 1848 (initproc)kqueue_event_init, /* tp_init */
1771 0, /* tp_alloc */ 1849 0, /* tp_alloc */
1772 0, /* tp_new */ 1850 0, /* tp_new */
1773 0, /* tp_free */ 1851 0, /* tp_free */
1774 }; 1852 };
1775 1853
1776 static PyObject * 1854 static PyObject *
1777 kqueue_queue_err_closed(void) 1855 kqueue_queue_err_closed(void)
1778 { 1856 {
1779 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd"); 1857 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object");
1780 return NULL; 1858 return NULL;
1781 } 1859 }
1782 1860
1783 static int 1861 static int
1784 kqueue_queue_internal_close(kqueue_queue_Object *self) 1862 kqueue_queue_internal_close(kqueue_queue_Object *self)
1785 { 1863 {
1786 int save_errno = 0; 1864 int save_errno = 0;
1787 if (self->kqfd >= 0) { 1865 if (self->kqfd >= 0) {
1788 int kqfd = self->kqfd; 1866 int kqfd = self->kqfd;
1789 self->kqfd = -1; 1867 self->kqfd = -1;
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after
2338 /* NETDEV filter flags */ 2416 /* NETDEV filter flags */
2339 #ifdef EVFILT_NETDEV 2417 #ifdef EVFILT_NETDEV
2340 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP); 2418 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2341 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN); 2419 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2342 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV); 2420 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
2343 #endif 2421 #endif
2344 2422
2345 #endif /* HAVE_KQUEUE */ 2423 #endif /* HAVE_KQUEUE */
2346 return m; 2424 return m;
2347 } 2425 }
OLDNEW
« Lib/test/test_epoll.py ('K') | « Lib/test/test_kqueue.py ('k') | no next file » | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+