This commit was manufactured by cvs2svn to create tag 'r234c1'.
[python/dscho.git] / Modules / selectmodule.c
blob11b93a9f59994f03d810b42e2277060b77983eed
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"
11 /* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
12 64 is too small (too many people have bumped into that limit).
13 Here we boost it.
14 Users who want even more than the boosted limit should #define
15 FD_SETSIZE higher before this; e.g., via compiler /D switch.
17 #if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
18 #define FD_SETSIZE 512
19 #endif
21 #if defined(HAVE_POLL_H)
22 #include <poll.h>
23 #elif defined(HAVE_SYS_POLL_H)
24 #include <sys/poll.h>
25 #endif
27 #ifdef __sgi
28 /* This is missing from unistd.h */
29 extern void bzero(void *, int);
30 #endif
32 #ifndef DONT_HAVE_SYS_TYPES_H
33 #include <sys/types.h>
34 #endif
36 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
37 #include <sys/time.h>
38 #include <utils.h>
39 #endif
41 #ifdef MS_WINDOWS
42 #include <winsock.h>
43 #else
44 #ifdef __BEOS__
45 #include <net/socket.h>
46 #define SOCKET int
47 #else
48 #define SOCKET int
49 #endif
50 #endif
53 static PyObject *SelectError;
55 /* list of Python objects and their file descriptor */
56 typedef struct {
57 PyObject *obj; /* owned reference */
58 SOCKET fd;
59 int sentinel; /* -1 == sentinel */
60 } pylist;
62 static void
63 reap_obj(pylist fd2obj[FD_SETSIZE + 1])
65 int i;
66 for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
67 Py_XDECREF(fd2obj[i].obj);
68 fd2obj[i].obj = NULL;
70 fd2obj[0].sentinel = -1;
74 /* returns -1 and sets the Python exception if an error occurred, otherwise
75 returns a number >= 0
77 static int
78 list2set(PyObject *list, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
80 int i;
81 int max = -1;
82 int index = 0;
83 int len = PyList_Size(list);
84 PyObject* o = NULL;
86 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
87 FD_ZERO(set);
89 for (i = 0; i < len; i++) {
90 SOCKET v;
92 /* any intervening fileno() calls could decr this refcnt */
93 if (!(o = PyList_GetItem(list, i)))
94 return -1;
96 Py_INCREF(o);
97 v = PyObject_AsFileDescriptor( o );
98 if (v == -1) goto finally;
100 #if defined(_MSC_VER)
101 max = 0; /* not used for Win32 */
102 #else /* !_MSC_VER */
103 if (v < 0 || v >= FD_SETSIZE) {
104 PyErr_SetString(PyExc_ValueError,
105 "filedescriptor out of range in select()");
106 goto finally;
108 if (v > max)
109 max = v;
110 #endif /* _MSC_VER */
111 FD_SET(v, set);
113 /* add object and its file descriptor to the list */
114 if (index >= FD_SETSIZE) {
115 PyErr_SetString(PyExc_ValueError,
116 "too many file descriptors in select()");
117 goto finally;
119 fd2obj[index].obj = o;
120 fd2obj[index].fd = v;
121 fd2obj[index].sentinel = 0;
122 fd2obj[++index].sentinel = -1;
124 return max+1;
126 finally:
127 Py_XDECREF(o);
128 return -1;
131 /* returns NULL and sets the Python exception if an error occurred */
132 static PyObject *
133 set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
135 int i, j, count=0;
136 PyObject *list, *o;
137 SOCKET fd;
139 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
140 if (FD_ISSET(fd2obj[j].fd, set))
141 count++;
143 list = PyList_New(count);
144 if (!list)
145 return NULL;
147 i = 0;
148 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
149 fd = fd2obj[j].fd;
150 if (FD_ISSET(fd, set)) {
151 #ifndef _MSC_VER
152 if (fd > FD_SETSIZE) {
153 PyErr_SetString(PyExc_SystemError,
154 "filedescriptor out of range returned in select()");
155 goto finally;
157 #endif
158 o = fd2obj[j].obj;
159 fd2obj[j].obj = NULL;
160 /* transfer ownership */
161 if (PyList_SetItem(list, i, o) < 0)
162 goto finally;
164 i++;
167 return list;
168 finally:
169 Py_DECREF(list);
170 return NULL;
173 #undef SELECT_USES_HEAP
174 #if FD_SETSIZE > 1024
175 #define SELECT_USES_HEAP
176 #endif /* FD_SETSIZE > 1024 */
178 static PyObject *
179 select_select(PyObject *self, PyObject *args)
181 #ifdef SELECT_USES_HEAP
182 pylist *rfd2obj, *wfd2obj, *efd2obj;
183 #else /* !SELECT_USES_HEAP */
184 /* XXX: All this should probably be implemented as follows:
185 * - find the highest descriptor we're interested in
186 * - add one
187 * - that's the size
188 * See: Stevens, APitUE, $12.5.1
190 pylist rfd2obj[FD_SETSIZE + 1];
191 pylist wfd2obj[FD_SETSIZE + 1];
192 pylist efd2obj[FD_SETSIZE + 1];
193 #endif /* SELECT_USES_HEAP */
194 PyObject *ifdlist, *ofdlist, *efdlist;
195 PyObject *ret = NULL;
196 PyObject *tout = Py_None;
197 fd_set ifdset, ofdset, efdset;
198 double timeout;
199 struct timeval tv, *tvp;
200 long seconds;
201 int imax, omax, emax, max;
202 int n;
204 /* convert arguments */
205 if (!PyArg_ParseTuple(args, "OOO|O:select",
206 &ifdlist, &ofdlist, &efdlist, &tout))
207 return NULL;
209 if (tout == Py_None)
210 tvp = (struct timeval *)0;
211 else if (!PyNumber_Check(tout)) {
212 PyErr_SetString(PyExc_TypeError,
213 "timeout must be a float or None");
214 return NULL;
216 else {
217 timeout = PyFloat_AsDouble(tout);
218 if (timeout == -1 && PyErr_Occurred())
219 return NULL;
220 if (timeout > (double)LONG_MAX) {
221 PyErr_SetString(PyExc_OverflowError,
222 "timeout period too long");
223 return NULL;
225 seconds = (long)timeout;
226 timeout = timeout - (double)seconds;
227 tv.tv_sec = seconds;
228 tv.tv_usec = (long)(timeout*1000000.0);
229 tvp = &tv;
232 /* sanity check first three arguments */
233 if (!PyList_Check(ifdlist) ||
234 !PyList_Check(ofdlist) ||
235 !PyList_Check(efdlist))
237 PyErr_SetString(PyExc_TypeError,
238 "arguments 1-3 must be lists");
239 return NULL;
242 #ifdef SELECT_USES_HEAP
243 /* Allocate memory for the lists */
244 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
245 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
246 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
247 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
248 if (rfd2obj) PyMem_DEL(rfd2obj);
249 if (wfd2obj) PyMem_DEL(wfd2obj);
250 if (efd2obj) PyMem_DEL(efd2obj);
251 return PyErr_NoMemory();
253 #endif /* SELECT_USES_HEAP */
254 /* Convert lists to fd_sets, and get maximum fd number
255 * propagates the Python exception set in list2set()
257 rfd2obj[0].sentinel = -1;
258 wfd2obj[0].sentinel = -1;
259 efd2obj[0].sentinel = -1;
260 if ((imax=list2set(ifdlist, &ifdset, rfd2obj)) < 0)
261 goto finally;
262 if ((omax=list2set(ofdlist, &ofdset, wfd2obj)) < 0)
263 goto finally;
264 if ((emax=list2set(efdlist, &efdset, efd2obj)) < 0)
265 goto finally;
266 max = imax;
267 if (omax > max) max = omax;
268 if (emax > max) max = emax;
270 Py_BEGIN_ALLOW_THREADS
271 n = select(max, &ifdset, &ofdset, &efdset, tvp);
272 Py_END_ALLOW_THREADS
274 #ifdef MS_WINDOWS
275 if (n == SOCKET_ERROR) {
276 PyErr_SetExcFromWindowsErr(SelectError, WSAGetLastError());
278 #else
279 if (n < 0) {
280 PyErr_SetFromErrno(SelectError);
282 #endif
283 else if (n == 0) {
284 /* optimization */
285 ifdlist = PyList_New(0);
286 if (ifdlist) {
287 ret = Py_BuildValue("OOO", ifdlist, ifdlist, ifdlist);
288 Py_DECREF(ifdlist);
291 else {
292 /* any of these three calls can raise an exception. it's more
293 convenient to test for this after all three calls... but
294 is that acceptable?
296 ifdlist = set2list(&ifdset, rfd2obj);
297 ofdlist = set2list(&ofdset, wfd2obj);
298 efdlist = set2list(&efdset, efd2obj);
299 if (PyErr_Occurred())
300 ret = NULL;
301 else
302 ret = Py_BuildValue("OOO", ifdlist, ofdlist, efdlist);
304 Py_DECREF(ifdlist);
305 Py_DECREF(ofdlist);
306 Py_DECREF(efdlist);
309 finally:
310 reap_obj(rfd2obj);
311 reap_obj(wfd2obj);
312 reap_obj(efd2obj);
313 #ifdef SELECT_USES_HEAP
314 PyMem_DEL(rfd2obj);
315 PyMem_DEL(wfd2obj);
316 PyMem_DEL(efd2obj);
317 #endif /* SELECT_USES_HEAP */
318 return ret;
321 #if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
323 * poll() support
326 typedef struct {
327 PyObject_HEAD
328 PyObject *dict;
329 int ufd_uptodate;
330 int ufd_len;
331 struct pollfd *ufds;
332 } pollObject;
334 static PyTypeObject poll_Type;
336 /* Update the malloc'ed array of pollfds to match the dictionary
337 contained within a pollObject. Return 1 on success, 0 on an error.
340 static int
341 update_ufd_array(pollObject *self)
343 int i, pos;
344 PyObject *key, *value;
346 self->ufd_len = PyDict_Size(self->dict);
347 PyMem_Resize(self->ufds, struct pollfd, self->ufd_len);
348 if (self->ufds == NULL) {
349 PyErr_NoMemory();
350 return 0;
353 i = pos = 0;
354 while (PyDict_Next(self->dict, &pos, &key, &value)) {
355 self->ufds[i].fd = PyInt_AsLong(key);
356 self->ufds[i].events = (short)PyInt_AsLong(value);
357 i++;
359 self->ufd_uptodate = 1;
360 return 1;
363 PyDoc_STRVAR(poll_register_doc,
364 "register(fd [, eventmask] ) -> None\n\n\
365 Register a file descriptor with the polling object.\n\
366 fd -- either an integer, or an object with a fileno() method returning an\n\
367 int.\n\
368 events -- an optional bitmask describing the type of events to check for");
370 static PyObject *
371 poll_register(pollObject *self, PyObject *args)
373 PyObject *o, *key, *value;
374 int fd, events = POLLIN | POLLPRI | POLLOUT;
375 int err;
377 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
378 return NULL;
381 fd = PyObject_AsFileDescriptor(o);
382 if (fd == -1) return NULL;
384 /* Add entry to the internal dictionary: the key is the
385 file descriptor, and the value is the event mask. */
386 key = PyInt_FromLong(fd);
387 if (key == NULL)
388 return NULL;
389 value = PyInt_FromLong(events);
390 if (value == NULL) {
391 Py_DECREF(key);
392 return NULL;
394 err = PyDict_SetItem(self->dict, key, value);
395 Py_DECREF(key);
396 Py_DECREF(value);
397 if (err < 0)
398 return NULL;
400 self->ufd_uptodate = 0;
402 Py_INCREF(Py_None);
403 return Py_None;
406 PyDoc_STRVAR(poll_unregister_doc,
407 "unregister(fd) -> None\n\n\
408 Remove a file descriptor being tracked by the polling object.");
410 static PyObject *
411 poll_unregister(pollObject *self, PyObject *args)
413 PyObject *o, *key;
414 int fd;
416 if (!PyArg_ParseTuple(args, "O:unregister", &o)) {
417 return NULL;
420 fd = PyObject_AsFileDescriptor( o );
421 if (fd == -1)
422 return NULL;
424 /* Check whether the fd is already in the array */
425 key = PyInt_FromLong(fd);
426 if (key == NULL)
427 return NULL;
429 if (PyDict_DelItem(self->dict, key) == -1) {
430 Py_DECREF(key);
431 /* This will simply raise the KeyError set by PyDict_DelItem
432 if the file descriptor isn't registered. */
433 return NULL;
436 Py_DECREF(key);
437 self->ufd_uptodate = 0;
439 Py_INCREF(Py_None);
440 return Py_None;
443 PyDoc_STRVAR(poll_poll_doc,
444 "poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
445 Polls the set of registered file descriptors, returning a list containing \n\
446 any descriptors that have events or errors to report.");
448 static PyObject *
449 poll_poll(pollObject *self, PyObject *args)
451 PyObject *result_list = NULL, *tout = NULL;
452 int timeout = 0, poll_result, i, j;
453 PyObject *value = NULL, *num = NULL;
455 if (!PyArg_ParseTuple(args, "|O:poll", &tout)) {
456 return NULL;
459 /* Check values for timeout */
460 if (tout == NULL || tout == Py_None)
461 timeout = -1;
462 else if (!PyNumber_Check(tout)) {
463 PyErr_SetString(PyExc_TypeError,
464 "timeout must be an integer or None");
465 return NULL;
467 else {
468 tout = PyNumber_Int(tout);
469 if (!tout)
470 return NULL;
471 timeout = PyInt_AsLong(tout);
472 Py_DECREF(tout);
475 /* Ensure the ufd array is up to date */
476 if (!self->ufd_uptodate)
477 if (update_ufd_array(self) == 0)
478 return NULL;
480 /* call poll() */
481 Py_BEGIN_ALLOW_THREADS;
482 poll_result = poll(self->ufds, self->ufd_len, timeout);
483 Py_END_ALLOW_THREADS;
485 if (poll_result < 0) {
486 PyErr_SetFromErrno(SelectError);
487 return NULL;
490 /* build the result list */
492 result_list = PyList_New(poll_result);
493 if (!result_list)
494 return NULL;
495 else {
496 for (i = 0, j = 0; j < poll_result; j++) {
497 /* skip to the next fired descriptor */
498 while (!self->ufds[i].revents) {
499 i++;
501 /* if we hit a NULL return, set value to NULL
502 and break out of loop; code at end will
503 clean up result_list */
504 value = PyTuple_New(2);
505 if (value == NULL)
506 goto error;
507 num = PyInt_FromLong(self->ufds[i].fd);
508 if (num == NULL) {
509 Py_DECREF(value);
510 goto error;
512 PyTuple_SET_ITEM(value, 0, num);
514 num = PyInt_FromLong(self->ufds[i].revents);
515 if (num == NULL) {
516 Py_DECREF(value);
517 goto error;
519 PyTuple_SET_ITEM(value, 1, num);
520 if ((PyList_SetItem(result_list, j, value)) == -1) {
521 Py_DECREF(value);
522 goto error;
524 i++;
527 return result_list;
529 error:
530 Py_DECREF(result_list);
531 return NULL;
534 static PyMethodDef poll_methods[] = {
535 {"register", (PyCFunction)poll_register,
536 METH_VARARGS, poll_register_doc},
537 {"unregister", (PyCFunction)poll_unregister,
538 METH_VARARGS, poll_unregister_doc},
539 {"poll", (PyCFunction)poll_poll,
540 METH_VARARGS, poll_poll_doc},
541 {NULL, NULL} /* sentinel */
544 static pollObject *
545 newPollObject(void)
547 pollObject *self;
548 self = PyObject_New(pollObject, &poll_Type);
549 if (self == NULL)
550 return NULL;
551 /* ufd_uptodate is a Boolean, denoting whether the
552 array pointed to by ufds matches the contents of the dictionary. */
553 self->ufd_uptodate = 0;
554 self->ufds = NULL;
555 self->dict = PyDict_New();
556 if (self->dict == NULL) {
557 Py_DECREF(self);
558 return NULL;
560 return self;
563 static void
564 poll_dealloc(pollObject *self)
566 if (self->ufds != NULL)
567 PyMem_DEL(self->ufds);
568 Py_XDECREF(self->dict);
569 PyObject_Del(self);
572 static PyObject *
573 poll_getattr(pollObject *self, char *name)
575 return Py_FindMethod(poll_methods, (PyObject *)self, name);
578 static PyTypeObject poll_Type = {
579 /* The ob_type field must be initialized in the module init function
580 * to be portable to Windows without using C++. */
581 PyObject_HEAD_INIT(NULL)
582 0, /*ob_size*/
583 "select.poll", /*tp_name*/
584 sizeof(pollObject), /*tp_basicsize*/
585 0, /*tp_itemsize*/
586 /* methods */
587 (destructor)poll_dealloc, /*tp_dealloc*/
588 0, /*tp_print*/
589 (getattrfunc)poll_getattr, /*tp_getattr*/
590 0, /*tp_setattr*/
591 0, /*tp_compare*/
592 0, /*tp_repr*/
593 0, /*tp_as_number*/
594 0, /*tp_as_sequence*/
595 0, /*tp_as_mapping*/
596 0, /*tp_hash*/
599 PyDoc_STRVAR(poll_doc,
600 "Returns a polling object, which supports registering and\n\
601 unregistering file descriptors, and then polling them for I/O events.");
603 static PyObject *
604 select_poll(PyObject *self, PyObject *args)
606 pollObject *rv;
608 if (!PyArg_ParseTuple(args, ":poll"))
609 return NULL;
610 rv = newPollObject();
611 if ( rv == NULL )
612 return NULL;
613 return (PyObject *)rv;
615 #endif /* HAVE_POLL && !HAVE_BROKEN_POLL */
617 PyDoc_STRVAR(select_doc,
618 "select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
620 Wait until one or more file descriptors are ready for some kind of I/O.\n\
621 The first three arguments are lists of file descriptors to be waited for:\n\
622 rlist -- wait until ready for reading\n\
623 wlist -- wait until ready for writing\n\
624 xlist -- wait for an ``exceptional condition''\n\
625 If only one kind of condition is required, pass [] for the other lists.\n\
626 A file descriptor is either a socket or file object, or a small integer\n\
627 gotten from a fileno() method call on one of those.\n\
629 The optional 4th argument specifies a timeout in seconds; it may be\n\
630 a floating point number to specify fractions of seconds. If it is absent\n\
631 or None, the call will never time out.\n\
633 The return value is a tuple of three lists corresponding to the first three\n\
634 arguments; each contains the subset of the corresponding file descriptors\n\
635 that are ready.\n\
637 *** IMPORTANT NOTICE ***\n\
638 On Windows, only sockets are supported; on Unix, all file descriptors.");
640 static PyMethodDef select_methods[] = {
641 {"select", select_select, METH_VARARGS, select_doc},
642 #if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
643 {"poll", select_poll, METH_VARARGS, poll_doc},
644 #endif /* HAVE_POLL && !HAVE_BROKEN_POLL */
645 {0, 0}, /* sentinel */
648 PyDoc_STRVAR(module_doc,
649 "This module supports asynchronous I/O on multiple file descriptors.\n\
651 *** IMPORTANT NOTICE ***\n\
652 On Windows, only sockets are supported; on Unix, all file descriptors.");
654 PyMODINIT_FUNC
655 initselect(void)
657 PyObject *m;
658 m = Py_InitModule3("select", select_methods, module_doc);
660 SelectError = PyErr_NewException("select.error", NULL, NULL);
661 Py_INCREF(SelectError);
662 PyModule_AddObject(m, "error", SelectError);
663 #if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
664 poll_Type.ob_type = &PyType_Type;
665 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
666 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
667 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
668 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
669 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
670 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
672 #ifdef POLLRDNORM
673 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
674 #endif
675 #ifdef POLLRDBAND
676 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
677 #endif
678 #ifdef POLLWRNORM
679 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
680 #endif
681 #ifdef POLLWRBAND
682 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
683 #endif
684 #ifdef POLLMSG
685 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
686 #endif
687 #endif /* HAVE_POLL && !HAVE_BROKEN_POLL */