source: python/trunk/Modules/selectmodule.c@ 560

Last change on this file since 560 was 391, checked in by dmik, 11 years ago

python: Merge vendor 2.7.6 to trunk.

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