move sections
[python/dscho.git] / Modules / selectmodule.c
blobc49c7b7add29bd1e9bff23e904059a6ae16a8899
1 /* select - Module containing unix select(2) call.
2 Under Unix, the file descriptors are small integers.
3 Under Win32, select only exists for sockets, and sockets may
4 have any value except INVALID_SOCKET.
5 Under BeOS, we suffer the same dichotomy as Win32; sockets can be anything
6 >= 0.
7 */
9 #include "Python.h"
10 #include <structmember.h>
12 #ifdef __APPLE__
13 /* Perform runtime testing for a broken poll on OSX to make it easier
14 * to use the same binary on multiple releases of the OS.
16 #undef HAVE_BROKEN_POLL
17 #endif
19 /* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
20 64 is too small (too many people have bumped into that limit).
21 Here we boost it.
22 Users who want even more than the boosted limit should #define
23 FD_SETSIZE higher before this; e.g., via compiler /D switch.
25 #if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
26 #define FD_SETSIZE 512
27 #endif
29 #if defined(HAVE_POLL_H)
30 #include <poll.h>
31 #elif defined(HAVE_SYS_POLL_H)
32 #include <sys/poll.h>
33 #endif
35 #ifdef __sgi
36 /* This is missing from unistd.h */
37 extern void bzero(void *, int);
38 #endif
40 #ifdef HAVE_SYS_TYPES_H
41 #include <sys/types.h>
42 #endif
44 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
45 #include <sys/time.h>
46 #include <utils.h>
47 #endif
49 #ifdef MS_WINDOWS
50 # include <winsock.h>
51 #else
52 # define SOCKET int
53 # ifdef __BEOS__
54 # include <net/socket.h>
55 # elif defined(__VMS)
56 # include <socket.h>
57 # endif
58 #endif
60 static PyObject *SelectError;
62 /* list of Python objects and their file descriptor */
63 typedef struct {
64 PyObject *obj; /* owned reference */
65 SOCKET fd;
66 int sentinel; /* -1 == sentinel */
67 } pylist;
69 static void
70 reap_obj(pylist fd2obj[FD_SETSIZE + 1])
72 int i;
73 for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
74 Py_XDECREF(fd2obj[i].obj);
75 fd2obj[i].obj = NULL;
77 fd2obj[0].sentinel = -1;
81 /* returns -1 and sets the Python exception if an error occurred, otherwise
82 returns a number >= 0
84 static int
85 seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
87 int i;
88 int max = -1;
89 int index = 0;
90 int len = -1;
91 PyObject* fast_seq = NULL;
92 PyObject* o = NULL;
94 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
95 FD_ZERO(set);
97 fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
98 if (!fast_seq)
99 return -1;
101 len = PySequence_Fast_GET_SIZE(fast_seq);
103 for (i = 0; i < len; i++) {
104 SOCKET v;
106 /* any intervening fileno() calls could decr this refcnt */
107 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
108 return -1;
110 Py_INCREF(o);
111 v = PyObject_AsFileDescriptor( o );
112 if (v == -1) goto finally;
114 #if defined(_MSC_VER)
115 max = 0; /* not used for Win32 */
116 #else /* !_MSC_VER */
117 if (v < 0 || v >= FD_SETSIZE) {
118 PyErr_SetString(PyExc_ValueError,
119 "filedescriptor out of range in select()");
120 goto finally;
122 if (v > max)
123 max = v;
124 #endif /* _MSC_VER */
125 FD_SET(v, set);
127 /* add object and its file descriptor to the list */
128 if (index >= FD_SETSIZE) {
129 PyErr_SetString(PyExc_ValueError,
130 "too many file descriptors in select()");
131 goto finally;
133 fd2obj[index].obj = o;
134 fd2obj[index].fd = v;
135 fd2obj[index].sentinel = 0;
136 fd2obj[++index].sentinel = -1;
138 Py_DECREF(fast_seq);
139 return max+1;
141 finally:
142 Py_XDECREF(o);
143 Py_DECREF(fast_seq);
144 return -1;
147 /* returns NULL and sets the Python exception if an error occurred */
148 static PyObject *
149 set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
151 int i, j, count=0;
152 PyObject *list, *o;
153 SOCKET fd;
155 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
156 if (FD_ISSET(fd2obj[j].fd, set))
157 count++;
159 list = PyList_New(count);
160 if (!list)
161 return NULL;
163 i = 0;
164 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
165 fd = fd2obj[j].fd;
166 if (FD_ISSET(fd, set)) {
167 #ifndef _MSC_VER
168 if (fd > FD_SETSIZE) {
169 PyErr_SetString(PyExc_SystemError,
170 "filedescriptor out of range returned in select()");
171 goto finally;
173 #endif
174 o = fd2obj[j].obj;
175 fd2obj[j].obj = NULL;
176 /* transfer ownership */
177 if (PyList_SetItem(list, i, o) < 0)
178 goto finally;
180 i++;
183 return list;
184 finally:
185 Py_DECREF(list);
186 return NULL;
189 #undef SELECT_USES_HEAP
190 #if FD_SETSIZE > 1024
191 #define SELECT_USES_HEAP
192 #endif /* FD_SETSIZE > 1024 */
194 static PyObject *
195 select_select(PyObject *self, PyObject *args)
197 #ifdef SELECT_USES_HEAP
198 pylist *rfd2obj, *wfd2obj, *efd2obj;
199 #else /* !SELECT_USES_HEAP */
200 /* XXX: All this should probably be implemented as follows:
201 * - find the highest descriptor we're interested in
202 * - add one
203 * - that's the size
204 * See: Stevens, APitUE, $12.5.1
206 pylist rfd2obj[FD_SETSIZE + 1];
207 pylist wfd2obj[FD_SETSIZE + 1];
208 pylist efd2obj[FD_SETSIZE + 1];
209 #endif /* SELECT_USES_HEAP */
210 PyObject *ifdlist, *ofdlist, *efdlist;
211 PyObject *ret = NULL;
212 PyObject *tout = Py_None;
213 fd_set ifdset, ofdset, efdset;
214 double timeout;
215 struct timeval tv, *tvp;
216 long seconds;
217 int imax, omax, emax, max;
218 int n;
220 /* convert arguments */
221 if (!PyArg_UnpackTuple(args, "select", 3, 4,
222 &ifdlist, &ofdlist, &efdlist, &tout))
223 return NULL;
225 if (tout == Py_None)
226 tvp = (struct timeval *)0;
227 else if (!PyNumber_Check(tout)) {
228 PyErr_SetString(PyExc_TypeError,
229 "timeout must be a float or None");
230 return NULL;
232 else {
233 timeout = PyFloat_AsDouble(tout);
234 if (timeout == -1 && PyErr_Occurred())
235 return NULL;
236 if (timeout > (double)LONG_MAX) {
237 PyErr_SetString(PyExc_OverflowError,
238 "timeout period too long");
239 return NULL;
241 seconds = (long)timeout;
242 timeout = timeout - (double)seconds;
243 tv.tv_sec = seconds;
244 tv.tv_usec = (long)(timeout * 1E6);
245 tvp = &tv;
249 #ifdef SELECT_USES_HEAP
250 /* Allocate memory for the lists */
251 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
252 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
253 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
254 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
255 if (rfd2obj) PyMem_DEL(rfd2obj);
256 if (wfd2obj) PyMem_DEL(wfd2obj);
257 if (efd2obj) PyMem_DEL(efd2obj);
258 return PyErr_NoMemory();
260 #endif /* SELECT_USES_HEAP */
261 /* Convert sequences to fd_sets, and get maximum fd number
262 * propagates the Python exception set in seq2set()
264 rfd2obj[0].sentinel = -1;
265 wfd2obj[0].sentinel = -1;
266 efd2obj[0].sentinel = -1;
267 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
268 goto finally;
269 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
270 goto finally;
271 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
272 goto finally;
273 max = imax;
274 if (omax > max) max = omax;
275 if (emax > max) max = emax;
277 Py_BEGIN_ALLOW_THREADS
278 n = select(max, &ifdset, &ofdset, &efdset, tvp);
279 Py_END_ALLOW_THREADS
281 #ifdef MS_WINDOWS
282 if (n == SOCKET_ERROR) {
283 PyErr_SetExcFromWindowsErr(SelectError, WSAGetLastError());
285 #else
286 if (n < 0) {
287 PyErr_SetFromErrno(SelectError);
289 #endif
290 else {
291 /* any of these three calls can raise an exception. it's more
292 convenient to test for this after all three calls... but
293 is that acceptable?
295 ifdlist = set2list(&ifdset, rfd2obj);
296 ofdlist = set2list(&ofdset, wfd2obj);
297 efdlist = set2list(&efdset, efd2obj);
298 if (PyErr_Occurred())
299 ret = NULL;
300 else
301 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
303 Py_DECREF(ifdlist);
304 Py_DECREF(ofdlist);
305 Py_DECREF(efdlist);
308 finally:
309 reap_obj(rfd2obj);
310 reap_obj(wfd2obj);
311 reap_obj(efd2obj);
312 #ifdef SELECT_USES_HEAP
313 PyMem_DEL(rfd2obj);
314 PyMem_DEL(wfd2obj);
315 PyMem_DEL(efd2obj);
316 #endif /* SELECT_USES_HEAP */
317 return ret;
320 #if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
322 * poll() support
325 typedef struct {
326 PyObject_HEAD
327 PyObject *dict;
328 int ufd_uptodate;
329 int ufd_len;
330 struct pollfd *ufds;
331 } pollObject;
333 static PyTypeObject poll_Type;
335 /* Update the malloc'ed array of pollfds to match the dictionary
336 contained within a pollObject. Return 1 on success, 0 on an error.
339 static int
340 update_ufd_array(pollObject *self)
342 Py_ssize_t i, pos;
343 PyObject *key, *value;
344 struct pollfd *old_ufds = self->ufds;
346 self->ufd_len = PyDict_Size(self->dict);
347 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
348 if (self->ufds == NULL) {
349 self->ufds = old_ufds;
350 PyErr_NoMemory();
351 return 0;
354 i = pos = 0;
355 while (PyDict_Next(self->dict, &pos, &key, &value)) {
356 self->ufds[i].fd = PyInt_AsLong(key);
357 self->ufds[i].events = (short)PyInt_AsLong(value);
358 i++;
360 self->ufd_uptodate = 1;
361 return 1;
364 PyDoc_STRVAR(poll_register_doc,
365 "register(fd [, eventmask] ) -> None\n\n\
366 Register a file descriptor with the polling object.\n\
367 fd -- either an integer, or an object with a fileno() method returning an\n\
368 int.\n\
369 events -- an optional bitmask describing the type of events to check for");
371 static PyObject *
372 poll_register(pollObject *self, PyObject *args)
374 PyObject *o, *key, *value;
375 int fd, events = POLLIN | POLLPRI | POLLOUT;
376 int err;
378 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
379 return NULL;
382 fd = PyObject_AsFileDescriptor(o);
383 if (fd == -1) return NULL;
385 /* Add entry to the internal dictionary: the key is the
386 file descriptor, and the value is the event mask. */
387 key = PyInt_FromLong(fd);
388 if (key == NULL)
389 return NULL;
390 value = PyInt_FromLong(events);
391 if (value == NULL) {
392 Py_DECREF(key);
393 return NULL;
395 err = PyDict_SetItem(self->dict, key, value);
396 Py_DECREF(key);
397 Py_DECREF(value);
398 if (err < 0)
399 return NULL;
401 self->ufd_uptodate = 0;
403 Py_INCREF(Py_None);
404 return Py_None;
407 PyDoc_STRVAR(poll_modify_doc,
408 "modify(fd, eventmask) -> None\n\n\
409 Modify an already registered file descriptor.\n\
410 fd -- either an integer, or an object with a fileno() method returning an\n\
411 int.\n\
412 events -- an optional bitmask describing the type of events to check for");
414 static PyObject *
415 poll_modify(pollObject *self, PyObject *args)
417 PyObject *o, *key, *value;
418 int fd, events;
419 int err;
421 if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) {
422 return NULL;
425 fd = PyObject_AsFileDescriptor(o);
426 if (fd == -1) return NULL;
428 /* Modify registered fd */
429 key = PyInt_FromLong(fd);
430 if (key == NULL)
431 return NULL;
432 if (PyDict_GetItem(self->dict, key) == NULL) {
433 errno = ENOENT;
434 PyErr_SetFromErrno(PyExc_IOError);
435 return NULL;
437 value = PyInt_FromLong(events);
438 if (value == NULL) {
439 Py_DECREF(key);
440 return NULL;
442 err = PyDict_SetItem(self->dict, key, value);
443 Py_DECREF(key);
444 Py_DECREF(value);
445 if (err < 0)
446 return NULL;
448 self->ufd_uptodate = 0;
450 Py_INCREF(Py_None);
451 return Py_None;
455 PyDoc_STRVAR(poll_unregister_doc,
456 "unregister(fd) -> None\n\n\
457 Remove a file descriptor being tracked by the polling object.");
459 static PyObject *
460 poll_unregister(pollObject *self, PyObject *o)
462 PyObject *key;
463 int fd;
465 fd = PyObject_AsFileDescriptor( o );
466 if (fd == -1)
467 return NULL;
469 /* Check whether the fd is already in the array */
470 key = PyInt_FromLong(fd);
471 if (key == NULL)
472 return NULL;
474 if (PyDict_DelItem(self->dict, key) == -1) {
475 Py_DECREF(key);
476 /* This will simply raise the KeyError set by PyDict_DelItem
477 if the file descriptor isn't registered. */
478 return NULL;
481 Py_DECREF(key);
482 self->ufd_uptodate = 0;
484 Py_INCREF(Py_None);
485 return Py_None;
488 PyDoc_STRVAR(poll_poll_doc,
489 "poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
490 Polls the set of registered file descriptors, returning a list containing \n\
491 any descriptors that have events or errors to report.");
493 static PyObject *
494 poll_poll(pollObject *self, PyObject *args)
496 PyObject *result_list = NULL, *tout = NULL;
497 int timeout = 0, poll_result, i, j;
498 PyObject *value = NULL, *num = NULL;
500 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
501 return NULL;
504 /* Check values for timeout */
505 if (tout == NULL || tout == Py_None)
506 timeout = -1;
507 else if (!PyNumber_Check(tout)) {
508 PyErr_SetString(PyExc_TypeError,
509 "timeout must be an integer or None");
510 return NULL;
512 else {
513 tout = PyNumber_Int(tout);
514 if (!tout)
515 return NULL;
516 timeout = PyInt_AsLong(tout);
517 Py_DECREF(tout);
518 if (timeout == -1 && PyErr_Occurred())
519 return NULL;
522 /* Ensure the ufd array is up to date */
523 if (!self->ufd_uptodate)
524 if (update_ufd_array(self) == 0)
525 return NULL;
527 /* call poll() */
528 Py_BEGIN_ALLOW_THREADS
529 poll_result = poll(self->ufds, self->ufd_len, timeout);
530 Py_END_ALLOW_THREADS
532 if (poll_result < 0) {
533 PyErr_SetFromErrno(SelectError);
534 return NULL;
537 /* build the result list */
539 result_list = PyList_New(poll_result);
540 if (!result_list)
541 return NULL;
542 else {
543 for (i = 0, j = 0; j < poll_result; j++) {
544 /* skip to the next fired descriptor */
545 while (!self->ufds[i].revents) {
546 i++;
548 /* if we hit a NULL return, set value to NULL
549 and break out of loop; code at end will
550 clean up result_list */
551 value = PyTuple_New(2);
552 if (value == NULL)
553 goto error;
554 num = PyInt_FromLong(self->ufds[i].fd);
555 if (num == NULL) {
556 Py_DECREF(value);
557 goto error;
559 PyTuple_SET_ITEM(value, 0, num);
561 /* The &0xffff is a workaround for AIX. 'revents'
562 is a 16-bit short, and IBM assigned POLLNVAL
563 to be 0x8000, so the conversion to int results
564 in a negative number. See SF bug #923315. */
565 num = PyInt_FromLong(self->ufds[i].revents & 0xffff);
566 if (num == NULL) {
567 Py_DECREF(value);
568 goto error;
570 PyTuple_SET_ITEM(value, 1, num);
571 if ((PyList_SetItem(result_list, j, value)) == -1) {
572 Py_DECREF(value);
573 goto error;
575 i++;
578 return result_list;
580 error:
581 Py_DECREF(result_list);
582 return NULL;
585 static PyMethodDef poll_methods[] = {
586 {"register", (PyCFunction)poll_register,
587 METH_VARARGS, poll_register_doc},
588 {"modify", (PyCFunction)poll_modify,
589 METH_VARARGS, poll_modify_doc},
590 {"unregister", (PyCFunction)poll_unregister,
591 METH_O, poll_unregister_doc},
592 {"poll", (PyCFunction)poll_poll,
593 METH_VARARGS, poll_poll_doc},
594 {NULL, NULL} /* sentinel */
597 static pollObject *
598 newPollObject(void)
600 pollObject *self;
601 self = PyObject_New(pollObject, &poll_Type);
602 if (self == NULL)
603 return NULL;
604 /* ufd_uptodate is a Boolean, denoting whether the
605 array pointed to by ufds matches the contents of the dictionary. */
606 self->ufd_uptodate = 0;
607 self->ufds = NULL;
608 self->dict = PyDict_New();
609 if (self->dict == NULL) {
610 Py_DECREF(self);
611 return NULL;
613 return self;
616 static void
617 poll_dealloc(pollObject *self)
619 if (self->ufds != NULL)
620 PyMem_DEL(self->ufds);
621 Py_XDECREF(self->dict);
622 PyObject_Del(self);
625 static PyObject *
626 poll_getattr(pollObject *self, char *name)
628 return Py_FindMethod(poll_methods, (PyObject *)self, name);
631 static PyTypeObject poll_Type = {
632 /* The ob_type field must be initialized in the module init function
633 * to be portable to Windows without using C++. */
634 PyVarObject_HEAD_INIT(NULL, 0)
635 "select.poll", /*tp_name*/
636 sizeof(pollObject), /*tp_basicsize*/
637 0, /*tp_itemsize*/
638 /* methods */
639 (destructor)poll_dealloc, /*tp_dealloc*/
640 0, /*tp_print*/
641 (getattrfunc)poll_getattr, /*tp_getattr*/
642 0, /*tp_setattr*/
643 0, /*tp_compare*/
644 0, /*tp_repr*/
645 0, /*tp_as_number*/
646 0, /*tp_as_sequence*/
647 0, /*tp_as_mapping*/
648 0, /*tp_hash*/
651 PyDoc_STRVAR(poll_doc,
652 "Returns a polling object, which supports registering and\n\
653 unregistering file descriptors, and then polling them for I/O events.");
655 static PyObject *
656 select_poll(PyObject *self, PyObject *unused)
658 return (PyObject *)newPollObject();
661 #ifdef __APPLE__
663 * On some systems poll() sets errno on invalid file descriptors. We test
664 * for this at runtime because this bug may be fixed or introduced between
665 * OS releases.
667 static int select_have_broken_poll(void)
669 int poll_test;
670 int filedes[2];
672 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
674 /* Create a file descriptor to make invalid */
675 if (pipe(filedes) < 0) {
676 return 1;
678 poll_struct.fd = filedes[0];
679 close(filedes[0]);
680 close(filedes[1]);
681 poll_test = poll(&poll_struct, 1, 0);
682 if (poll_test < 0) {
683 return 1;
684 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
685 return 1;
687 return 0;
689 #endif /* __APPLE__ */
691 #endif /* HAVE_POLL */
693 #ifdef HAVE_EPOLL
694 /* **************************************************************************
695 * epoll interface for Linux 2.6
697 * Written by Christian Heimes
698 * Inspired by Twisted's _epoll.pyx and select.poll()
701 #ifdef HAVE_SYS_EPOLL_H
702 #include <sys/epoll.h>
703 #endif
705 typedef struct {
706 PyObject_HEAD
707 SOCKET epfd; /* epoll control file descriptor */
708 } pyEpoll_Object;
710 static PyTypeObject pyEpoll_Type;
711 #define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
713 static PyObject *
714 pyepoll_err_closed(void)
716 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
717 return NULL;
720 static int
721 pyepoll_internal_close(pyEpoll_Object *self)
723 int save_errno = 0;
724 if (self->epfd >= 0) {
725 int epfd = self->epfd;
726 self->epfd = -1;
727 Py_BEGIN_ALLOW_THREADS
728 if (close(epfd) < 0)
729 save_errno = errno;
730 Py_END_ALLOW_THREADS
732 return save_errno;
735 static PyObject *
736 newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
738 pyEpoll_Object *self;
740 if (sizehint == -1) {
741 sizehint = FD_SETSIZE-1;
743 else if (sizehint < 1) {
744 PyErr_Format(PyExc_ValueError,
745 "sizehint must be greater zero, got %d",
746 sizehint);
747 return NULL;
750 assert(type != NULL && type->tp_alloc != NULL);
751 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
752 if (self == NULL)
753 return NULL;
755 if (fd == -1) {
756 Py_BEGIN_ALLOW_THREADS
757 self->epfd = epoll_create(sizehint);
758 Py_END_ALLOW_THREADS
760 else {
761 self->epfd = fd;
763 if (self->epfd < 0) {
764 Py_DECREF(self);
765 PyErr_SetFromErrno(PyExc_IOError);
766 return NULL;
768 return (PyObject *)self;
772 static PyObject *
773 pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
775 int sizehint = -1;
776 static char *kwlist[] = {"sizehint", NULL};
778 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:epoll", kwlist,
779 &sizehint))
780 return NULL;
782 return newPyEpoll_Object(type, sizehint, -1);
786 static void
787 pyepoll_dealloc(pyEpoll_Object *self)
789 (void)pyepoll_internal_close(self);
790 Py_TYPE(self)->tp_free(self);
793 static PyObject*
794 pyepoll_close(pyEpoll_Object *self)
796 errno = pyepoll_internal_close(self);
797 if (errno < 0) {
798 PyErr_SetFromErrno(PyExc_IOError);
799 return NULL;
801 Py_RETURN_NONE;
804 PyDoc_STRVAR(pyepoll_close_doc,
805 "close() -> None\n\
807 Close the epoll control file descriptor. Further operations on the epoll\n\
808 object will raise an exception.");
810 static PyObject*
811 pyepoll_get_closed(pyEpoll_Object *self)
813 if (self->epfd < 0)
814 Py_RETURN_TRUE;
815 else
816 Py_RETURN_FALSE;
819 static PyObject*
820 pyepoll_fileno(pyEpoll_Object *self)
822 if (self->epfd < 0)
823 return pyepoll_err_closed();
824 return PyInt_FromLong(self->epfd);
827 PyDoc_STRVAR(pyepoll_fileno_doc,
828 "fileno() -> int\n\
830 Return the epoll control file descriptor.");
832 static PyObject*
833 pyepoll_fromfd(PyObject *cls, PyObject *args)
835 SOCKET fd;
837 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
838 return NULL;
840 return newPyEpoll_Object((PyTypeObject*)cls, -1, fd);
843 PyDoc_STRVAR(pyepoll_fromfd_doc,
844 "fromfd(fd) -> epoll\n\
846 Create an epoll object from a given control fd.");
848 static PyObject *
849 pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
851 struct epoll_event ev;
852 int result;
853 int fd;
855 if (epfd < 0)
856 return pyepoll_err_closed();
858 fd = PyObject_AsFileDescriptor(pfd);
859 if (fd == -1) {
860 return NULL;
863 switch(op) {
864 case EPOLL_CTL_ADD:
865 case EPOLL_CTL_MOD:
866 ev.events = events;
867 ev.data.fd = fd;
868 Py_BEGIN_ALLOW_THREADS
869 result = epoll_ctl(epfd, op, fd, &ev);
870 Py_END_ALLOW_THREADS
871 break;
872 case EPOLL_CTL_DEL:
873 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
874 * operation required a non-NULL pointer in event, even
875 * though this argument is ignored. */
876 Py_BEGIN_ALLOW_THREADS
877 result = epoll_ctl(epfd, op, fd, &ev);
878 if (errno == EBADF) {
879 /* fd already closed */
880 result = 0;
881 errno = 0;
883 Py_END_ALLOW_THREADS
884 break;
885 default:
886 result = -1;
887 errno = EINVAL;
890 if (result < 0) {
891 PyErr_SetFromErrno(PyExc_IOError);
892 return NULL;
894 Py_RETURN_NONE;
897 static PyObject *
898 pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
900 PyObject *pfd;
901 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
902 static char *kwlist[] = {"fd", "eventmask", NULL};
904 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
905 &pfd, &events)) {
906 return NULL;
909 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
912 PyDoc_STRVAR(pyepoll_register_doc,
913 "register(fd[, eventmask]) -> bool\n\
915 Registers a new fd or modifies an already registered fd. register() returns\n\
916 True if a new fd was registered or False if the event mask for fd was modified.\n\
917 fd is the target file descriptor of the operation.\n\
918 events is a bit set composed of the various EPOLL constants; the default\n\
919 is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
921 The epoll interface supports all file descriptors that support poll.");
923 static PyObject *
924 pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
926 PyObject *pfd;
927 unsigned int events;
928 static char *kwlist[] = {"fd", "eventmask", NULL};
930 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
931 &pfd, &events)) {
932 return NULL;
935 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
938 PyDoc_STRVAR(pyepoll_modify_doc,
939 "modify(fd, eventmask) -> None\n\
941 fd is the target file descriptor of the operation\n\
942 events is a bit set composed of the various EPOLL constants");
944 static PyObject *
945 pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
947 PyObject *pfd;
948 static char *kwlist[] = {"fd", NULL};
950 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
951 &pfd)) {
952 return NULL;
955 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
958 PyDoc_STRVAR(pyepoll_unregister_doc,
959 "unregister(fd) -> None\n\
961 fd is the target file descriptor of the operation.");
963 static PyObject *
964 pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
966 double dtimeout = -1.;
967 int timeout;
968 int maxevents = -1;
969 int nfds, i;
970 PyObject *elist = NULL, *etuple = NULL;
971 struct epoll_event *evs = NULL;
972 static char *kwlist[] = {"timeout", "maxevents", NULL};
974 if (self->epfd < 0)
975 return pyepoll_err_closed();
977 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
978 &dtimeout, &maxevents)) {
979 return NULL;
982 if (dtimeout < 0) {
983 timeout = -1;
985 else if (dtimeout * 1000.0 > INT_MAX) {
986 PyErr_SetString(PyExc_OverflowError,
987 "timeout is too large");
988 return NULL;
990 else {
991 timeout = (int)(dtimeout * 1000.0);
994 if (maxevents == -1) {
995 maxevents = FD_SETSIZE-1;
997 else if (maxevents < 1) {
998 PyErr_Format(PyExc_ValueError,
999 "maxevents must be greater than 0, got %d",
1000 maxevents);
1001 return NULL;
1004 evs = PyMem_New(struct epoll_event, maxevents);
1005 if (evs == NULL) {
1006 Py_DECREF(self);
1007 PyErr_NoMemory();
1008 return NULL;
1011 Py_BEGIN_ALLOW_THREADS
1012 nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
1013 Py_END_ALLOW_THREADS
1014 if (nfds < 0) {
1015 PyErr_SetFromErrno(PyExc_IOError);
1016 goto error;
1019 elist = PyList_New(nfds);
1020 if (elist == NULL) {
1021 goto error;
1024 for (i = 0; i < nfds; i++) {
1025 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
1026 if (etuple == NULL) {
1027 Py_CLEAR(elist);
1028 goto error;
1030 PyList_SET_ITEM(elist, i, etuple);
1033 error:
1034 PyMem_Free(evs);
1035 return elist;
1038 PyDoc_STRVAR(pyepoll_poll_doc,
1039 "poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1041 Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1042 in seconds (as float). -1 makes poll wait indefinitely.\n\
1043 Up to maxevents are returned to the caller.");
1045 static PyMethodDef pyepoll_methods[] = {
1046 {"fromfd", (PyCFunction)pyepoll_fromfd,
1047 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1048 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1049 pyepoll_close_doc},
1050 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1051 pyepoll_fileno_doc},
1052 {"modify", (PyCFunction)pyepoll_modify,
1053 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1054 {"register", (PyCFunction)pyepoll_register,
1055 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1056 {"unregister", (PyCFunction)pyepoll_unregister,
1057 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1058 {"poll", (PyCFunction)pyepoll_poll,
1059 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
1060 {NULL, NULL},
1063 static PyGetSetDef pyepoll_getsetlist[] = {
1064 {"closed", (getter)pyepoll_get_closed, NULL,
1065 "True if the epoll handler is closed"},
1066 {0},
1069 PyDoc_STRVAR(pyepoll_doc,
1070 "select.epoll([sizehint=-1])\n\
1072 Returns an epolling object\n\
1074 sizehint must be a positive integer or -1 for the default size. The\n\
1075 sizehint is used to optimize internal data structures. It doesn't limit\n\
1076 the maximum number of monitored events.");
1078 static PyTypeObject pyEpoll_Type = {
1079 PyVarObject_HEAD_INIT(NULL, 0)
1080 "select.epoll", /* tp_name */
1081 sizeof(pyEpoll_Object), /* tp_basicsize */
1082 0, /* tp_itemsize */
1083 (destructor)pyepoll_dealloc, /* tp_dealloc */
1084 0, /* tp_print */
1085 0, /* tp_getattr */
1086 0, /* tp_setattr */
1087 0, /* tp_compare */
1088 0, /* tp_repr */
1089 0, /* tp_as_number */
1090 0, /* tp_as_sequence */
1091 0, /* tp_as_mapping */
1092 0, /* tp_hash */
1093 0, /* tp_call */
1094 0, /* tp_str */
1095 PyObject_GenericGetAttr, /* tp_getattro */
1096 0, /* tp_setattro */
1097 0, /* tp_as_buffer */
1098 Py_TPFLAGS_DEFAULT, /* tp_flags */
1099 pyepoll_doc, /* tp_doc */
1100 0, /* tp_traverse */
1101 0, /* tp_clear */
1102 0, /* tp_richcompare */
1103 0, /* tp_weaklistoffset */
1104 0, /* tp_iter */
1105 0, /* tp_iternext */
1106 pyepoll_methods, /* tp_methods */
1107 0, /* tp_members */
1108 pyepoll_getsetlist, /* tp_getset */
1109 0, /* tp_base */
1110 0, /* tp_dict */
1111 0, /* tp_descr_get */
1112 0, /* tp_descr_set */
1113 0, /* tp_dictoffset */
1114 0, /* tp_init */
1115 0, /* tp_alloc */
1116 pyepoll_new, /* tp_new */
1117 0, /* tp_free */
1120 #endif /* HAVE_EPOLL */
1122 #ifdef HAVE_KQUEUE
1123 /* **************************************************************************
1124 * kqueue interface for BSD
1126 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1127 * All rights reserved.
1129 * Redistribution and use in source and binary forms, with or without
1130 * modification, are permitted provided that the following conditions
1131 * are met:
1132 * 1. Redistributions of source code must retain the above copyright
1133 * notice, this list of conditions and the following disclaimer.
1134 * 2. Redistributions in binary form must reproduce the above copyright
1135 * notice, this list of conditions and the following disclaimer in the
1136 * documentation and/or other materials provided with the distribution.
1138 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1139 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1140 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1141 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1142 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1143 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1144 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1145 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1146 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1147 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1148 * SUCH DAMAGE.
1151 #ifdef HAVE_SYS_EVENT_H
1152 #include <sys/event.h>
1153 #endif
1155 PyDoc_STRVAR(kqueue_event_doc,
1156 "kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
1158 This object is the equivalent of the struct kevent for the C API.\n\
1160 See the kqueue manpage for more detailed information about the meaning\n\
1161 of the arguments.\n\
1163 One minor note: while you might hope that udata could store a\n\
1164 reference to a python object, it cannot, because it is impossible to\n\
1165 keep a proper reference count of the object once it's passed into the\n\
1166 kernel. Therefore, I have restricted it to only storing an integer. I\n\
1167 recommend ignoring it and simply using the 'ident' field to key off\n\
1168 of. You could also set up a dictionary on the python side to store a\n\
1169 udata->object mapping.");
1171 typedef struct {
1172 PyObject_HEAD
1173 struct kevent e;
1174 } kqueue_event_Object;
1176 static PyTypeObject kqueue_event_Type;
1178 #define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1180 typedef struct {
1181 PyObject_HEAD
1182 SOCKET kqfd; /* kqueue control fd */
1183 } kqueue_queue_Object;
1185 static PyTypeObject kqueue_queue_Type;
1187 #define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1189 #if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1190 # error uintptr_t does not match void *!
1191 #elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1192 # define T_UINTPTRT T_ULONGLONG
1193 # define T_INTPTRT T_LONGLONG
1194 # define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1195 # define UINTPTRT_FMT_UNIT "K"
1196 # define INTPTRT_FMT_UNIT "L"
1197 #elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1198 # define T_UINTPTRT T_ULONG
1199 # define T_INTPTRT T_LONG
1200 # define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1201 # define UINTPTRT_FMT_UNIT "k"
1202 # define INTPTRT_FMT_UNIT "l"
1203 #elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1204 # define T_UINTPTRT T_UINT
1205 # define T_INTPTRT T_INT
1206 # define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1207 # define UINTPTRT_FMT_UNIT "I"
1208 # define INTPTRT_FMT_UNIT "i"
1209 #else
1210 # error uintptr_t does not match int, long, or long long!
1211 #endif
1213 /* Unfortunately, we can't store python objects in udata, because
1214 * kevents in the kernel can be removed without warning, which would
1215 * forever lose the refcount on the object stored with it.
1218 #define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1219 static struct PyMemberDef kqueue_event_members[] = {
1220 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1221 {"filter", T_SHORT, KQ_OFF(e.filter)},
1222 {"flags", T_USHORT, KQ_OFF(e.flags)},
1223 {"fflags", T_UINT, KQ_OFF(e.fflags)},
1224 {"data", T_INTPTRT, KQ_OFF(e.data)},
1225 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1226 {NULL} /* Sentinel */
1228 #undef KQ_OFF
1230 static PyObject *
1232 kqueue_event_repr(kqueue_event_Object *s)
1234 char buf[1024];
1235 PyOS_snprintf(
1236 buf, sizeof(buf),
1237 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1238 "data=0x%zd udata=%p>",
1239 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1240 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1241 return PyString_FromString(buf);
1244 static int
1245 kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1247 PyObject *pfd;
1248 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1249 "data", "udata", NULL};
1250 static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
1252 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
1254 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1255 &pfd, &(self->e.filter), &(self->e.flags),
1256 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1257 return -1;
1260 if (PyLong_Check(pfd)) {
1261 self->e.ident = PyLong_AsUintptr_t(pfd);
1263 else {
1264 self->e.ident = PyObject_AsFileDescriptor(pfd);
1266 if (PyErr_Occurred()) {
1267 return -1;
1269 return 0;
1272 static PyObject *
1273 kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
1274 int op)
1276 Py_intptr_t result = 0;
1278 if (!kqueue_event_Check(o)) {
1279 if (op == Py_EQ || op == Py_NE) {
1280 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1281 Py_INCREF(res);
1282 return res;
1284 PyErr_Format(PyExc_TypeError,
1285 "can't compare %.200s to %.200s",
1286 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1287 return NULL;
1289 if (((result = s->e.ident - o->e.ident) == 0) &&
1290 ((result = s->e.filter - o->e.filter) == 0) &&
1291 ((result = s->e.flags - o->e.flags) == 0) &&
1292 ((result = s->e.fflags - o->e.fflags) == 0) &&
1293 ((result = s->e.data - o->e.data) == 0) &&
1294 ((result = s->e.udata - o->e.udata) == 0)
1296 result = 0;
1299 switch (op) {
1300 case Py_EQ:
1301 result = (result == 0);
1302 break;
1303 case Py_NE:
1304 result = (result != 0);
1305 break;
1306 case Py_LE:
1307 result = (result <= 0);
1308 break;
1309 case Py_GE:
1310 result = (result >= 0);
1311 break;
1312 case Py_LT:
1313 result = (result < 0);
1314 break;
1315 case Py_GT:
1316 result = (result > 0);
1317 break;
1319 return PyBool_FromLong((long)result);
1322 static PyTypeObject kqueue_event_Type = {
1323 PyVarObject_HEAD_INIT(NULL, 0)
1324 "select.kevent", /* tp_name */
1325 sizeof(kqueue_event_Object), /* tp_basicsize */
1326 0, /* tp_itemsize */
1327 0, /* tp_dealloc */
1328 0, /* tp_print */
1329 0, /* tp_getattr */
1330 0, /* tp_setattr */
1331 0, /* tp_compare */
1332 (reprfunc)kqueue_event_repr, /* tp_repr */
1333 0, /* tp_as_number */
1334 0, /* tp_as_sequence */
1335 0, /* tp_as_mapping */
1336 0, /* tp_hash */
1337 0, /* tp_call */
1338 0, /* tp_str */
1339 0, /* tp_getattro */
1340 0, /* tp_setattro */
1341 0, /* tp_as_buffer */
1342 Py_TPFLAGS_DEFAULT, /* tp_flags */
1343 kqueue_event_doc, /* tp_doc */
1344 0, /* tp_traverse */
1345 0, /* tp_clear */
1346 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1347 0, /* tp_weaklistoffset */
1348 0, /* tp_iter */
1349 0, /* tp_iternext */
1350 0, /* tp_methods */
1351 kqueue_event_members, /* tp_members */
1352 0, /* tp_getset */
1353 0, /* tp_base */
1354 0, /* tp_dict */
1355 0, /* tp_descr_get */
1356 0, /* tp_descr_set */
1357 0, /* tp_dictoffset */
1358 (initproc)kqueue_event_init, /* tp_init */
1359 0, /* tp_alloc */
1360 0, /* tp_new */
1361 0, /* tp_free */
1364 static PyObject *
1365 kqueue_queue_err_closed(void)
1367 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1368 return NULL;
1371 static int
1372 kqueue_queue_internal_close(kqueue_queue_Object *self)
1374 int save_errno = 0;
1375 if (self->kqfd >= 0) {
1376 int kqfd = self->kqfd;
1377 self->kqfd = -1;
1378 Py_BEGIN_ALLOW_THREADS
1379 if (close(kqfd) < 0)
1380 save_errno = errno;
1381 Py_END_ALLOW_THREADS
1383 return save_errno;
1386 static PyObject *
1387 newKqueue_Object(PyTypeObject *type, SOCKET fd)
1389 kqueue_queue_Object *self;
1390 assert(type != NULL && type->tp_alloc != NULL);
1391 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1392 if (self == NULL) {
1393 return NULL;
1396 if (fd == -1) {
1397 Py_BEGIN_ALLOW_THREADS
1398 self->kqfd = kqueue();
1399 Py_END_ALLOW_THREADS
1401 else {
1402 self->kqfd = fd;
1404 if (self->kqfd < 0) {
1405 Py_DECREF(self);
1406 PyErr_SetFromErrno(PyExc_IOError);
1407 return NULL;
1409 return (PyObject *)self;
1412 static PyObject *
1413 kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1416 if ((args != NULL && PyObject_Size(args)) ||
1417 (kwds != NULL && PyObject_Size(kwds))) {
1418 PyErr_SetString(PyExc_ValueError,
1419 "select.kqueue doesn't accept arguments");
1420 return NULL;
1423 return newKqueue_Object(type, -1);
1426 static void
1427 kqueue_queue_dealloc(kqueue_queue_Object *self)
1429 kqueue_queue_internal_close(self);
1430 Py_TYPE(self)->tp_free(self);
1433 static PyObject*
1434 kqueue_queue_close(kqueue_queue_Object *self)
1436 errno = kqueue_queue_internal_close(self);
1437 if (errno < 0) {
1438 PyErr_SetFromErrno(PyExc_IOError);
1439 return NULL;
1441 Py_RETURN_NONE;
1444 PyDoc_STRVAR(kqueue_queue_close_doc,
1445 "close() -> None\n\
1447 Close the kqueue control file descriptor. Further operations on the kqueue\n\
1448 object will raise an exception.");
1450 static PyObject*
1451 kqueue_queue_get_closed(kqueue_queue_Object *self)
1453 if (self->kqfd < 0)
1454 Py_RETURN_TRUE;
1455 else
1456 Py_RETURN_FALSE;
1459 static PyObject*
1460 kqueue_queue_fileno(kqueue_queue_Object *self)
1462 if (self->kqfd < 0)
1463 return kqueue_queue_err_closed();
1464 return PyInt_FromLong(self->kqfd);
1467 PyDoc_STRVAR(kqueue_queue_fileno_doc,
1468 "fileno() -> int\n\
1470 Return the kqueue control file descriptor.");
1472 static PyObject*
1473 kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1475 SOCKET fd;
1477 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1478 return NULL;
1480 return newKqueue_Object((PyTypeObject*)cls, fd);
1483 PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1484 "fromfd(fd) -> kqueue\n\
1486 Create a kqueue object from a given control fd.");
1488 static PyObject *
1489 kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1491 int nevents = 0;
1492 int gotevents = 0;
1493 int nchanges = 0;
1494 int i = 0;
1495 PyObject *otimeout = NULL;
1496 PyObject *ch = NULL;
1497 PyObject *it = NULL, *ei = NULL;
1498 PyObject *result = NULL;
1499 struct kevent *evl = NULL;
1500 struct kevent *chl = NULL;
1501 struct timespec timeoutspec;
1502 struct timespec *ptimeoutspec;
1504 if (self->kqfd < 0)
1505 return kqueue_queue_err_closed();
1507 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1508 return NULL;
1510 if (nevents < 0) {
1511 PyErr_Format(PyExc_ValueError,
1512 "Length of eventlist must be 0 or positive, got %d",
1513 nevents);
1514 return NULL;
1517 if (otimeout == Py_None || otimeout == NULL) {
1518 ptimeoutspec = NULL;
1520 else if (PyNumber_Check(otimeout)) {
1521 double timeout;
1522 long seconds;
1524 timeout = PyFloat_AsDouble(otimeout);
1525 if (timeout == -1 && PyErr_Occurred())
1526 return NULL;
1527 if (timeout > (double)LONG_MAX) {
1528 PyErr_SetString(PyExc_OverflowError,
1529 "timeout period too long");
1530 return NULL;
1532 if (timeout < 0) {
1533 PyErr_SetString(PyExc_ValueError,
1534 "timeout must be positive or None");
1535 return NULL;
1538 seconds = (long)timeout;
1539 timeout = timeout - (double)seconds;
1540 timeoutspec.tv_sec = seconds;
1541 timeoutspec.tv_nsec = (long)(timeout * 1E9);
1542 ptimeoutspec = &timeoutspec;
1544 else {
1545 PyErr_Format(PyExc_TypeError,
1546 "timeout argument must be an number "
1547 "or None, got %.200s",
1548 Py_TYPE(otimeout)->tp_name);
1549 return NULL;
1552 if (ch != NULL && ch != Py_None) {
1553 it = PyObject_GetIter(ch);
1554 if (it == NULL) {
1555 PyErr_SetString(PyExc_TypeError,
1556 "changelist is not iterable");
1557 return NULL;
1559 nchanges = PyObject_Size(ch);
1560 if (nchanges < 0) {
1561 goto error;
1564 chl = PyMem_New(struct kevent, nchanges);
1565 if (chl == NULL) {
1566 PyErr_NoMemory();
1567 goto error;
1569 i = 0;
1570 while ((ei = PyIter_Next(it)) != NULL) {
1571 if (!kqueue_event_Check(ei)) {
1572 Py_DECREF(ei);
1573 PyErr_SetString(PyExc_TypeError,
1574 "changelist must be an iterable of "
1575 "select.kevent objects");
1576 goto error;
1577 } else {
1578 chl[i++] = ((kqueue_event_Object *)ei)->e;
1580 Py_DECREF(ei);
1583 Py_CLEAR(it);
1585 /* event list */
1586 if (nevents) {
1587 evl = PyMem_New(struct kevent, nevents);
1588 if (evl == NULL) {
1589 PyErr_NoMemory();
1590 goto error;
1594 Py_BEGIN_ALLOW_THREADS
1595 gotevents = kevent(self->kqfd, chl, nchanges,
1596 evl, nevents, ptimeoutspec);
1597 Py_END_ALLOW_THREADS
1599 if (gotevents == -1) {
1600 PyErr_SetFromErrno(PyExc_OSError);
1601 goto error;
1604 result = PyList_New(gotevents);
1605 if (result == NULL) {
1606 goto error;
1609 for (i = 0; i < gotevents; i++) {
1610 kqueue_event_Object *ch;
1612 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1613 if (ch == NULL) {
1614 goto error;
1616 ch->e = evl[i];
1617 PyList_SET_ITEM(result, i, (PyObject *)ch);
1619 PyMem_Free(chl);
1620 PyMem_Free(evl);
1621 return result;
1623 error:
1624 PyMem_Free(chl);
1625 PyMem_Free(evl);
1626 Py_XDECREF(result);
1627 Py_XDECREF(it);
1628 return NULL;
1631 PyDoc_STRVAR(kqueue_queue_control_doc,
1632 "control(changelist, max_events[, timeout=None]) -> eventlist\n\
1634 Calls the kernel kevent function.\n\
1635 - changelist must be a list of kevent objects describing the changes\n\
1636 to be made to the kernel's watch list or None.\n\
1637 - max_events lets you specify the maximum number of events that the\n\
1638 kernel will return.\n\
1639 - timeout is the maximum time to wait in seconds, or else None,\n\
1640 to wait forever. timeout accepts floats for smaller timeouts, too.");
1643 static PyMethodDef kqueue_queue_methods[] = {
1644 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
1645 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
1646 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
1647 kqueue_queue_close_doc},
1648 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
1649 kqueue_queue_fileno_doc},
1650 {"control", (PyCFunction)kqueue_queue_control,
1651 METH_VARARGS , kqueue_queue_control_doc},
1652 {NULL, NULL},
1655 static PyGetSetDef kqueue_queue_getsetlist[] = {
1656 {"closed", (getter)kqueue_queue_get_closed, NULL,
1657 "True if the kqueue handler is closed"},
1658 {0},
1661 PyDoc_STRVAR(kqueue_queue_doc,
1662 "Kqueue syscall wrapper.\n\
1664 For example, to start watching a socket for input:\n\
1665 >>> kq = kqueue()\n\
1666 >>> sock = socket()\n\
1667 >>> sock.connect((host, port))\n\
1668 >>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
1670 To wait one second for it to become writeable:\n\
1671 >>> kq.control(None, 1, 1000)\n\
1673 To stop listening:\n\
1674 >>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
1676 static PyTypeObject kqueue_queue_Type = {
1677 PyVarObject_HEAD_INIT(NULL, 0)
1678 "select.kqueue", /* tp_name */
1679 sizeof(kqueue_queue_Object), /* tp_basicsize */
1680 0, /* tp_itemsize */
1681 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
1682 0, /* tp_print */
1683 0, /* tp_getattr */
1684 0, /* tp_setattr */
1685 0, /* tp_compare */
1686 0, /* tp_repr */
1687 0, /* tp_as_number */
1688 0, /* tp_as_sequence */
1689 0, /* tp_as_mapping */
1690 0, /* tp_hash */
1691 0, /* tp_call */
1692 0, /* tp_str */
1693 0, /* tp_getattro */
1694 0, /* tp_setattro */
1695 0, /* tp_as_buffer */
1696 Py_TPFLAGS_DEFAULT, /* tp_flags */
1697 kqueue_queue_doc, /* tp_doc */
1698 0, /* tp_traverse */
1699 0, /* tp_clear */
1700 0, /* tp_richcompare */
1701 0, /* tp_weaklistoffset */
1702 0, /* tp_iter */
1703 0, /* tp_iternext */
1704 kqueue_queue_methods, /* tp_methods */
1705 0, /* tp_members */
1706 kqueue_queue_getsetlist, /* tp_getset */
1707 0, /* tp_base */
1708 0, /* tp_dict */
1709 0, /* tp_descr_get */
1710 0, /* tp_descr_set */
1711 0, /* tp_dictoffset */
1712 0, /* tp_init */
1713 0, /* tp_alloc */
1714 kqueue_queue_new, /* tp_new */
1715 0, /* tp_free */
1718 #endif /* HAVE_KQUEUE */
1719 /* ************************************************************************ */
1721 PyDoc_STRVAR(select_doc,
1722 "select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
1724 Wait until one or more file descriptors are ready for some kind of I/O.\n\
1725 The first three arguments are sequences of file descriptors to be waited for:\n\
1726 rlist -- wait until ready for reading\n\
1727 wlist -- wait until ready for writing\n\
1728 xlist -- wait for an ``exceptional condition''\n\
1729 If only one kind of condition is required, pass [] for the other lists.\n\
1730 A file descriptor is either a socket or file object, or a small integer\n\
1731 gotten from a fileno() method call on one of those.\n\
1733 The optional 4th argument specifies a timeout in seconds; it may be\n\
1734 a floating point number to specify fractions of seconds. If it is absent\n\
1735 or None, the call will never time out.\n\
1737 The return value is a tuple of three lists corresponding to the first three\n\
1738 arguments; each contains the subset of the corresponding file descriptors\n\
1739 that are ready.\n\
1741 *** IMPORTANT NOTICE ***\n\
1742 On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
1743 descriptors can be used.");
1745 static PyMethodDef select_methods[] = {
1746 {"select", select_select, METH_VARARGS, select_doc},
1747 #ifdef HAVE_POLL
1748 {"poll", select_poll, METH_NOARGS, poll_doc},
1749 #endif /* HAVE_POLL */
1750 {0, 0}, /* sentinel */
1753 PyDoc_STRVAR(module_doc,
1754 "This module supports asynchronous I/O on multiple file descriptors.\n\
1756 *** IMPORTANT NOTICE ***\n\
1757 On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
1759 PyMODINIT_FUNC
1760 initselect(void)
1762 PyObject *m;
1763 m = Py_InitModule3("select", select_methods, module_doc);
1764 if (m == NULL)
1765 return;
1767 SelectError = PyErr_NewException("select.error", NULL, NULL);
1768 Py_INCREF(SelectError);
1769 PyModule_AddObject(m, "error", SelectError);
1771 #ifdef PIPE_BUF
1772 PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
1773 #endif
1775 #if defined(HAVE_POLL)
1776 #ifdef __APPLE__
1777 if (select_have_broken_poll()) {
1778 if (PyObject_DelAttrString(m, "poll") == -1) {
1779 PyErr_Clear();
1781 } else {
1782 #else
1784 #endif
1785 Py_TYPE(&poll_Type) = &PyType_Type;
1786 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
1787 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
1788 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
1789 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
1790 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
1791 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
1793 #ifdef POLLRDNORM
1794 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
1795 #endif
1796 #ifdef POLLRDBAND
1797 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
1798 #endif
1799 #ifdef POLLWRNORM
1800 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
1801 #endif
1802 #ifdef POLLWRBAND
1803 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
1804 #endif
1805 #ifdef POLLMSG
1806 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
1807 #endif
1809 #endif /* HAVE_POLL */
1811 #ifdef HAVE_EPOLL
1812 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
1813 if (PyType_Ready(&pyEpoll_Type) < 0)
1814 return;
1816 Py_INCREF(&pyEpoll_Type);
1817 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
1819 PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
1820 PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
1821 PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
1822 PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
1823 PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
1824 PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
1825 #ifdef EPOLLONESHOT
1826 /* Kernel 2.6.2+ */
1827 PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
1828 #endif
1829 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
1830 PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
1831 PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
1832 PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
1833 PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
1834 PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
1835 #endif /* HAVE_EPOLL */
1837 #ifdef HAVE_KQUEUE
1838 kqueue_event_Type.tp_new = PyType_GenericNew;
1839 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
1840 if(PyType_Ready(&kqueue_event_Type) < 0)
1841 return;
1843 Py_INCREF(&kqueue_event_Type);
1844 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
1846 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
1847 if(PyType_Ready(&kqueue_queue_Type) < 0)
1848 return;
1849 Py_INCREF(&kqueue_queue_Type);
1850 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
1852 /* event filters */
1853 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
1854 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
1855 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
1856 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
1857 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
1858 #ifdef EVFILT_NETDEV
1859 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
1860 #endif
1861 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
1862 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
1864 /* event flags */
1865 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
1866 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
1867 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
1868 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
1869 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
1870 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
1872 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
1873 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
1875 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
1876 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
1878 /* READ WRITE filter flag */
1879 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
1881 /* VNODE filter flags */
1882 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
1883 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
1884 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
1885 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
1886 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
1887 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
1888 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
1890 /* PROC filter flags */
1891 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
1892 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
1893 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
1894 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
1895 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
1897 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
1898 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
1899 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
1901 /* NETDEV filter flags */
1902 #ifdef EVFILT_NETDEV
1903 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
1904 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
1905 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
1906 #endif
1908 #endif /* HAVE_KQUEUE */