Updated for 2.1a3
[python/dscho.git] / Modules / selectmodule.c
blobde910c6077e1643b27de5e7e1ea088fa696b8875
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 #ifdef HAVE_UNISTD_H
22 #include <unistd.h>
23 #endif
24 #ifdef HAVE_POLL_H
25 #include <poll.h>
26 #endif
28 #ifdef __sgi
29 /* This is missing from unistd.h */
30 extern void bzero(void *, int);
31 #endif
33 #ifndef DONT_HAVE_SYS_TYPES_H
34 #include <sys/types.h>
35 #endif
37 #if defined(PYOS_OS2)
38 #include <sys/time.h>
39 #include <utils.h>
40 #endif
42 #ifdef MS_WINDOWS
43 #include <winsock.h>
44 #else
45 #ifdef __BEOS__
46 #include <net/socket.h>
47 #define SOCKET int
48 #else
49 #define SOCKET int
50 #endif
51 #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 + 3])
65 int i;
66 for (i = 0; i < FD_SETSIZE + 3 && 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 + 3])
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 + 3])
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;
174 static PyObject *
175 select_select(PyObject *self, PyObject *args)
177 #ifdef MS_WINDOWS
178 /* This would be an awful lot of stack space on Windows! */
179 pylist *rfd2obj, *wfd2obj, *efd2obj;
180 #else
181 pylist rfd2obj[FD_SETSIZE + 3];
182 pylist wfd2obj[FD_SETSIZE + 3];
183 pylist efd2obj[FD_SETSIZE + 3];
184 #endif
185 PyObject *ifdlist, *ofdlist, *efdlist;
186 PyObject *ret = NULL;
187 PyObject *tout = Py_None;
188 fd_set ifdset, ofdset, efdset;
189 double timeout;
190 struct timeval tv, *tvp;
191 long seconds;
192 int imax, omax, emax, max;
193 int n;
195 /* convert arguments */
196 if (!PyArg_ParseTuple(args, "OOO|O:select",
197 &ifdlist, &ofdlist, &efdlist, &tout))
198 return NULL;
200 if (tout == Py_None)
201 tvp = (struct timeval *)0;
202 else if (!PyArg_Parse(tout, "d", &timeout)) {
203 PyErr_SetString(PyExc_TypeError,
204 "timeout must be a float or None");
205 return NULL;
207 else {
208 if (timeout > (double)LONG_MAX) {
209 PyErr_SetString(PyExc_OverflowError, "timeout period too long");
210 return NULL;
212 seconds = (long)timeout;
213 timeout = timeout - (double)seconds;
214 tv.tv_sec = seconds;
215 tv.tv_usec = (long)(timeout*1000000.0);
216 tvp = &tv;
219 /* sanity check first three arguments */
220 if (!PyList_Check(ifdlist) ||
221 !PyList_Check(ofdlist) ||
222 !PyList_Check(efdlist))
224 PyErr_SetString(PyExc_TypeError,
225 "arguments 1-3 must be lists");
226 return NULL;
229 #ifdef MS_WINDOWS
230 /* Allocate memory for the lists */
231 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 3);
232 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 3);
233 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 3);
234 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
235 if (rfd2obj) PyMem_DEL(rfd2obj);
236 if (wfd2obj) PyMem_DEL(wfd2obj);
237 if (efd2obj) PyMem_DEL(efd2obj);
238 return NULL;
240 #endif
241 /* Convert lists to fd_sets, and get maximum fd number
242 * propagates the Python exception set in list2set()
244 rfd2obj[0].sentinel = -1;
245 wfd2obj[0].sentinel = -1;
246 efd2obj[0].sentinel = -1;
247 if ((imax=list2set(ifdlist, &ifdset, rfd2obj)) < 0)
248 goto finally;
249 if ((omax=list2set(ofdlist, &ofdset, wfd2obj)) < 0)
250 goto finally;
251 if ((emax=list2set(efdlist, &efdset, efd2obj)) < 0)
252 goto finally;
253 max = imax;
254 if (omax > max) max = omax;
255 if (emax > max) max = emax;
257 Py_BEGIN_ALLOW_THREADS
258 n = select(max, &ifdset, &ofdset, &efdset, tvp);
259 Py_END_ALLOW_THREADS
261 if (n < 0) {
262 PyErr_SetFromErrno(SelectError);
264 else if (n == 0) {
265 /* optimization */
266 ifdlist = PyList_New(0);
267 if (ifdlist) {
268 ret = Py_BuildValue("OOO", ifdlist, ifdlist, ifdlist);
269 Py_DECREF(ifdlist);
272 else {
273 /* any of these three calls can raise an exception. it's more
274 convenient to test for this after all three calls... but
275 is that acceptable?
277 ifdlist = set2list(&ifdset, rfd2obj);
278 ofdlist = set2list(&ofdset, wfd2obj);
279 efdlist = set2list(&efdset, efd2obj);
280 if (PyErr_Occurred())
281 ret = NULL;
282 else
283 ret = Py_BuildValue("OOO", ifdlist, ofdlist, efdlist);
285 Py_DECREF(ifdlist);
286 Py_DECREF(ofdlist);
287 Py_DECREF(efdlist);
290 finally:
291 reap_obj(rfd2obj);
292 reap_obj(wfd2obj);
293 reap_obj(efd2obj);
294 #ifdef MS_WINDOWS
295 PyMem_DEL(rfd2obj);
296 PyMem_DEL(wfd2obj);
297 PyMem_DEL(efd2obj);
298 #endif
299 return ret;
302 #ifdef HAVE_POLL
304 * poll() support
307 typedef struct {
308 PyObject_HEAD
309 PyObject *dict;
310 int ufd_uptodate;
311 int ufd_len;
312 struct pollfd *ufds;
313 } pollObject;
315 staticforward PyTypeObject poll_Type;
317 /* Update the malloc'ed array of pollfds to match the dictionary
318 contained within a pollObject. Return 1 on success, 0 on an error.
321 static int
322 update_ufd_array(pollObject *self)
324 int i, j, pos;
325 PyObject *key, *value;
327 self->ufd_len = PyDict_Size(self->dict);
328 PyMem_Resize(self->ufds, struct pollfd, self->ufd_len);
329 if (self->ufds == NULL) {
330 PyErr_NoMemory();
331 return 0;
334 i = pos = 0;
335 while ((j = PyDict_Next(self->dict, &pos, &key, &value))) {
336 self->ufds[i].fd = PyInt_AsLong(key);
337 self->ufds[i].events = PyInt_AsLong(value);
338 i++;
340 self->ufd_uptodate = 1;
341 return 1;
344 static char poll_register_doc[] =
345 "register(fd [, eventmask] ) -> None\n\n\
346 Register a file descriptor with the polling object.\n\
347 fd -- either an integer, or an object with a fileno() method returning an int.\n\
348 events -- an optional bitmask describing the type of events to check for";
350 static PyObject *
351 poll_register(pollObject *self, PyObject *args)
353 PyObject *o, *key, *value;
354 int fd, events = POLLIN | POLLPRI | POLLOUT;
356 if (!PyArg_ParseTuple(args, "O|i", &o, &events)) {
357 return NULL;
360 fd = PyObject_AsFileDescriptor(o);
361 if (fd == -1) return NULL;
363 /* Add entry to the internal dictionary: the key is the
364 file descriptor, and the value is the event mask. */
365 if ( (NULL == (key = PyInt_FromLong(fd))) ||
366 (NULL == (value = PyInt_FromLong(events))) ||
367 (PyDict_SetItem(self->dict, key, value)) == -1) {
368 return NULL;
370 self->ufd_uptodate = 0;
372 Py_INCREF(Py_None);
373 return Py_None;
376 static char poll_unregister_doc[] =
377 "unregister(fd) -> None\n\n\
378 Remove a file descriptor being tracked by the polling object.";
380 static PyObject *
381 poll_unregister(pollObject *self, PyObject *args)
383 PyObject *o, *key;
384 int fd;
386 if (!PyArg_ParseTuple(args, "O", &o)) {
387 return NULL;
390 fd = PyObject_AsFileDescriptor( o );
391 if (fd == -1)
392 return NULL;
394 /* Check whether the fd is already in the array */
395 key = PyInt_FromLong(fd);
396 if (key == NULL)
397 return NULL;
399 if (PyDict_DelItem(self->dict, key) == -1) {
400 Py_DECREF(key);
401 /* This will simply raise the KeyError set by PyDict_DelItem
402 if the file descriptor isn't registered. */
403 return NULL;
406 Py_DECREF(key);
407 self->ufd_uptodate = 0;
409 Py_INCREF(Py_None);
410 return Py_None;
413 static char poll_poll_doc[] =
414 "poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
415 Polls the set of registered file descriptors, returning a list containing \n\
416 any descriptors that have events or errors to report.";
418 static PyObject *
419 poll_poll(pollObject *self, PyObject *args)
421 PyObject *result_list = NULL, *tout = NULL;
422 int timeout = 0, poll_result, i, j;
423 PyObject *value = NULL, *num = NULL;
425 if (!PyArg_ParseTuple(args, "|O", &tout)) {
426 return NULL;
429 /* Check values for timeout */
430 if (tout == NULL || tout == Py_None)
431 timeout = -1;
432 else if (!PyArg_Parse(tout, "i", &timeout)) {
433 PyErr_SetString(PyExc_TypeError,
434 "timeout must be an integer or None");
435 return NULL;
438 /* Ensure the ufd array is up to date */
439 if (!self->ufd_uptodate)
440 if (update_ufd_array(self) == 0)
441 return NULL;
443 /* call poll() */
444 Py_BEGIN_ALLOW_THREADS;
445 poll_result = poll(self->ufds, self->ufd_len, timeout);
446 Py_END_ALLOW_THREADS;
448 if (poll_result < 0) {
449 PyErr_SetFromErrno(SelectError);
450 return NULL;
453 /* build the result list */
455 result_list = PyList_New(poll_result);
456 if (!result_list)
457 return NULL;
458 else {
459 for (i = 0, j = 0; j < poll_result; j++) {
460 /* skip to the next fired descriptor */
461 while (!self->ufds[i].revents) {
462 i++;
464 /* if we hit a NULL return, set value to NULL
465 and break out of loop; code at end will
466 clean up result_list */
467 value = PyTuple_New(2);
468 if (value == NULL)
469 goto error;
470 num = PyInt_FromLong(self->ufds[i].fd);
471 if (num == NULL) {
472 Py_DECREF(value);
473 goto error;
475 PyTuple_SET_ITEM(value, 0, num);
477 num = PyInt_FromLong(self->ufds[i].revents);
478 if (num == NULL) {
479 Py_DECREF(value);
480 goto error;
482 PyTuple_SET_ITEM(value, 1, num);
483 if ((PyList_SetItem(result_list, j, value)) == -1) {
484 Py_DECREF(value);
485 goto error;
487 i++;
490 return result_list;
492 error:
493 Py_DECREF(result_list);
494 return NULL;
497 static PyMethodDef poll_methods[] = {
498 {"register", (PyCFunction)poll_register,
499 METH_VARARGS, poll_register_doc},
500 {"unregister", (PyCFunction)poll_unregister,
501 METH_VARARGS, poll_unregister_doc},
502 {"poll", (PyCFunction)poll_poll,
503 METH_VARARGS, poll_poll_doc},
504 {NULL, NULL} /* sentinel */
507 static pollObject *
508 newPollObject(void)
510 pollObject *self;
511 self = PyObject_New(pollObject, &poll_Type);
512 if (self == NULL)
513 return NULL;
514 /* ufd_uptodate is a Boolean, denoting whether the
515 array pointed to by ufds matches the contents of the dictionary. */
516 self->ufd_uptodate = 0;
517 self->ufds = NULL;
518 self->dict = PyDict_New();
519 if (self->dict == NULL) {
520 Py_DECREF(self);
521 return NULL;
523 return self;
526 static void
527 poll_dealloc(pollObject *self)
529 if (self->ufds != NULL)
530 PyMem_DEL(self->ufds);
531 Py_XDECREF(self->dict);
532 PyObject_Del(self);
535 static PyObject *
536 poll_getattr(pollObject *self, char *name)
538 return Py_FindMethod(poll_methods, (PyObject *)self, name);
541 statichere PyTypeObject poll_Type = {
542 /* The ob_type field must be initialized in the module init function
543 * to be portable to Windows without using C++. */
544 PyObject_HEAD_INIT(NULL)
545 0, /*ob_size*/
546 "poll", /*tp_name*/
547 sizeof(pollObject), /*tp_basicsize*/
548 0, /*tp_itemsize*/
549 /* methods */
550 (destructor)poll_dealloc, /*tp_dealloc*/
551 0, /*tp_print*/
552 (getattrfunc)poll_getattr, /*tp_getattr*/
553 0, /*tp_setattr*/
554 0, /*tp_compare*/
555 0, /*tp_repr*/
556 0, /*tp_as_number*/
557 0, /*tp_as_sequence*/
558 0, /*tp_as_mapping*/
559 0, /*tp_hash*/
562 static char poll_doc[] =
563 "Returns a polling object, which supports registering and\n\
564 unregistering file descriptors, and then polling them for I/O events.";
566 static PyObject *
567 select_poll(PyObject *self, PyObject *args)
569 pollObject *rv;
571 if (!PyArg_ParseTuple(args, ":poll"))
572 return NULL;
573 rv = newPollObject();
574 if ( rv == NULL )
575 return NULL;
576 return (PyObject *)rv;
578 #endif /* HAVE_POLL */
580 static char select_doc[] =
581 "select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
583 Wait until one or more file descriptors are ready for some kind of I/O.\n\
584 The first three arguments are lists of file descriptors to be waited for:\n\
585 rlist -- wait until ready for reading\n\
586 wlist -- wait until ready for writing\n\
587 xlist -- wait for an ``exceptional condition''\n\
588 If only one kind of condition is required, pass [] for the other lists.\n\
589 A file descriptor is either a socket or file object, or a small integer\n\
590 gotten from a fileno() method call on one of those.\n\
592 The optional 4th argument specifies a timeout in seconds; it may be\n\
593 a floating point number to specify fractions of seconds. If it is absent\n\
594 or None, the call will never time out.\n\
596 The return value is a tuple of three lists corresponding to the first three\n\
597 arguments; each contains the subset of the corresponding file descriptors\n\
598 that are ready.\n\
600 *** IMPORTANT NOTICE ***\n\
601 On Windows, only sockets are supported; on Unix, all file descriptors.";
603 static PyMethodDef select_methods[] = {
604 {"select", select_select, METH_VARARGS, select_doc},
605 #ifdef HAVE_POLL
606 {"poll", select_poll, METH_VARARGS, poll_doc},
607 #endif /* HAVE_POLL */
608 {0, 0}, /* sentinel */
611 static char module_doc[] =
612 "This module supports asynchronous I/O on multiple file descriptors.\n\
614 *** IMPORTANT NOTICE ***\n\
615 On Windows, only sockets are supported; on Unix, all file descriptors.";
618 * Convenience routine to export an integer value.
619 * For simplicity, errors (which are unlikely anyway) are ignored.
622 static void
623 insint(PyObject *d, char *name, int value)
625 PyObject *v = PyInt_FromLong((long) value);
626 if (v == NULL) {
627 /* Don't bother reporting this error */
628 PyErr_Clear();
630 else {
631 PyDict_SetItemString(d, name, v);
632 Py_DECREF(v);
636 DL_EXPORT(void)
637 initselect(void)
639 PyObject *m, *d;
640 m = Py_InitModule3("select", select_methods, module_doc);
641 d = PyModule_GetDict(m);
642 SelectError = PyErr_NewException("select.error", NULL, NULL);
643 PyDict_SetItemString(d, "error", SelectError);
644 #ifdef HAVE_POLL
645 poll_Type.ob_type = &PyType_Type;
646 insint(d, "POLLIN", POLLIN);
647 insint(d, "POLLPRI", POLLPRI);
648 insint(d, "POLLOUT", POLLOUT);
649 insint(d, "POLLERR", POLLERR);
650 insint(d, "POLLHUP", POLLHUP);
651 insint(d, "POLLNVAL", POLLNVAL);
653 #ifdef POLLRDNORM
654 insint(d, "POLLRDNORM", POLLRDNORM);
655 #endif
656 #ifdef POLLRDBAND
657 insint(d, "POLLRDBAND", POLLRDBAND);
658 #endif
659 #ifdef POLLWRNORM
660 insint(d, "POLLWRNORM", POLLWRNORM);
661 #endif
662 #ifdef POLLWRBAND
663 insint(d, "POLLWRBAND", POLLWRBAND);
664 #endif
665 #ifdef POLLMSG
666 insint(d, "POLLMSG", POLLMSG);
667 #endif
668 #endif /* HAVE_POLL */