This commit was manufactured by cvs2svn to create tag 'r221'.
[python/dscho.git] / Modules / selectmodule.c
blobceaf3fa92d20c286907088f7059dd496eb610a7b
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)
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 (!PyArg_Parse(tout, "d", &timeout)) {
212 PyErr_SetString(PyExc_TypeError,
213 "timeout must be a float or None");
214 return NULL;
216 else {
217 if (timeout > (double)LONG_MAX) {
218 PyErr_SetString(PyExc_OverflowError,
219 "timeout period too long");
220 return NULL;
222 seconds = (long)timeout;
223 timeout = timeout - (double)seconds;
224 tv.tv_sec = seconds;
225 tv.tv_usec = (long)(timeout*1000000.0);
226 tvp = &tv;
229 /* sanity check first three arguments */
230 if (!PyList_Check(ifdlist) ||
231 !PyList_Check(ofdlist) ||
232 !PyList_Check(efdlist))
234 PyErr_SetString(PyExc_TypeError,
235 "arguments 1-3 must be lists");
236 return NULL;
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 NULL;
250 #endif /* SELECT_USES_HEAP */
251 /* Convert lists to fd_sets, and get maximum fd number
252 * propagates the Python exception set in list2set()
254 rfd2obj[0].sentinel = -1;
255 wfd2obj[0].sentinel = -1;
256 efd2obj[0].sentinel = -1;
257 if ((imax=list2set(ifdlist, &ifdset, rfd2obj)) < 0)
258 goto finally;
259 if ((omax=list2set(ofdlist, &ofdset, wfd2obj)) < 0)
260 goto finally;
261 if ((emax=list2set(efdlist, &efdset, efd2obj)) < 0)
262 goto finally;
263 max = imax;
264 if (omax > max) max = omax;
265 if (emax > max) max = emax;
267 Py_BEGIN_ALLOW_THREADS
268 n = select(max, &ifdset, &ofdset, &efdset, tvp);
269 Py_END_ALLOW_THREADS
271 if (n < 0) {
272 PyErr_SetFromErrno(SelectError);
274 else if (n == 0) {
275 /* optimization */
276 ifdlist = PyList_New(0);
277 if (ifdlist) {
278 ret = Py_BuildValue("OOO", ifdlist, ifdlist, ifdlist);
279 Py_DECREF(ifdlist);
282 else {
283 /* any of these three calls can raise an exception. it's more
284 convenient to test for this after all three calls... but
285 is that acceptable?
287 ifdlist = set2list(&ifdset, rfd2obj);
288 ofdlist = set2list(&ofdset, wfd2obj);
289 efdlist = set2list(&efdset, efd2obj);
290 if (PyErr_Occurred())
291 ret = NULL;
292 else
293 ret = Py_BuildValue("OOO", ifdlist, ofdlist, efdlist);
295 Py_DECREF(ifdlist);
296 Py_DECREF(ofdlist);
297 Py_DECREF(efdlist);
300 finally:
301 reap_obj(rfd2obj);
302 reap_obj(wfd2obj);
303 reap_obj(efd2obj);
304 #ifdef SELECT_USES_HEAP
305 PyMem_DEL(rfd2obj);
306 PyMem_DEL(wfd2obj);
307 PyMem_DEL(efd2obj);
308 #endif /* SELECT_USES_HEAP */
309 return ret;
312 #ifdef HAVE_POLL
314 * poll() support
317 typedef struct {
318 PyObject_HEAD
319 PyObject *dict;
320 int ufd_uptodate;
321 int ufd_len;
322 struct pollfd *ufds;
323 } pollObject;
325 staticforward PyTypeObject poll_Type;
327 /* Update the malloc'ed array of pollfds to match the dictionary
328 contained within a pollObject. Return 1 on success, 0 on an error.
331 static int
332 update_ufd_array(pollObject *self)
334 int i, pos;
335 PyObject *key, *value;
337 self->ufd_len = PyDict_Size(self->dict);
338 PyMem_Resize(self->ufds, struct pollfd, self->ufd_len);
339 if (self->ufds == NULL) {
340 PyErr_NoMemory();
341 return 0;
344 i = pos = 0;
345 while (PyDict_Next(self->dict, &pos, &key, &value)) {
346 self->ufds[i].fd = PyInt_AsLong(key);
347 self->ufds[i].events = (short)PyInt_AsLong(value);
348 i++;
350 self->ufd_uptodate = 1;
351 return 1;
354 static char poll_register_doc[] =
355 "register(fd [, eventmask] ) -> None\n\n\
356 Register a file descriptor with the polling object.\n\
357 fd -- either an integer, or an object with a fileno() method returning an\n\
358 int.\n\
359 events -- an optional bitmask describing the type of events to check for";
361 static PyObject *
362 poll_register(pollObject *self, PyObject *args)
364 PyObject *o, *key, *value;
365 int fd, events = POLLIN | POLLPRI | POLLOUT;
366 int err;
368 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
369 return NULL;
372 fd = PyObject_AsFileDescriptor(o);
373 if (fd == -1) return NULL;
375 /* Add entry to the internal dictionary: the key is the
376 file descriptor, and the value is the event mask. */
377 key = PyInt_FromLong(fd);
378 if (key == NULL)
379 return NULL;
380 value = PyInt_FromLong(events);
381 if (value == NULL) {
382 Py_DECREF(key);
383 return NULL;
385 err = PyDict_SetItem(self->dict, key, value);
386 Py_DECREF(key);
387 Py_DECREF(value);
388 if (err < 0)
389 return NULL;
391 self->ufd_uptodate = 0;
393 Py_INCREF(Py_None);
394 return Py_None;
397 static char poll_unregister_doc[] =
398 "unregister(fd) -> None\n\n\
399 Remove a file descriptor being tracked by the polling object.";
401 static PyObject *
402 poll_unregister(pollObject *self, PyObject *args)
404 PyObject *o, *key;
405 int fd;
407 if (!PyArg_ParseTuple(args, "O:unregister", &o)) {
408 return NULL;
411 fd = PyObject_AsFileDescriptor( o );
412 if (fd == -1)
413 return NULL;
415 /* Check whether the fd is already in the array */
416 key = PyInt_FromLong(fd);
417 if (key == NULL)
418 return NULL;
420 if (PyDict_DelItem(self->dict, key) == -1) {
421 Py_DECREF(key);
422 /* This will simply raise the KeyError set by PyDict_DelItem
423 if the file descriptor isn't registered. */
424 return NULL;
427 Py_DECREF(key);
428 self->ufd_uptodate = 0;
430 Py_INCREF(Py_None);
431 return Py_None;
434 static char poll_poll_doc[] =
435 "poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
436 Polls the set of registered file descriptors, returning a list containing \n\
437 any descriptors that have events or errors to report.";
439 static PyObject *
440 poll_poll(pollObject *self, PyObject *args)
442 PyObject *result_list = NULL, *tout = NULL;
443 int timeout = 0, poll_result, i, j;
444 PyObject *value = NULL, *num = NULL;
446 if (!PyArg_ParseTuple(args, "|O:poll", &tout)) {
447 return NULL;
450 /* Check values for timeout */
451 if (tout == NULL || tout == Py_None)
452 timeout = -1;
453 else if (!PyArg_Parse(tout, "i", &timeout)) {
454 PyErr_SetString(PyExc_TypeError,
455 "timeout must be an integer or None");
456 return NULL;
459 /* Ensure the ufd array is up to date */
460 if (!self->ufd_uptodate)
461 if (update_ufd_array(self) == 0)
462 return NULL;
464 /* call poll() */
465 Py_BEGIN_ALLOW_THREADS;
466 poll_result = poll(self->ufds, self->ufd_len, timeout);
467 Py_END_ALLOW_THREADS;
469 if (poll_result < 0) {
470 PyErr_SetFromErrno(SelectError);
471 return NULL;
474 /* build the result list */
476 result_list = PyList_New(poll_result);
477 if (!result_list)
478 return NULL;
479 else {
480 for (i = 0, j = 0; j < poll_result; j++) {
481 /* skip to the next fired descriptor */
482 while (!self->ufds[i].revents) {
483 i++;
485 /* if we hit a NULL return, set value to NULL
486 and break out of loop; code at end will
487 clean up result_list */
488 value = PyTuple_New(2);
489 if (value == NULL)
490 goto error;
491 num = PyInt_FromLong(self->ufds[i].fd);
492 if (num == NULL) {
493 Py_DECREF(value);
494 goto error;
496 PyTuple_SET_ITEM(value, 0, num);
498 num = PyInt_FromLong(self->ufds[i].revents);
499 if (num == NULL) {
500 Py_DECREF(value);
501 goto error;
503 PyTuple_SET_ITEM(value, 1, num);
504 if ((PyList_SetItem(result_list, j, value)) == -1) {
505 Py_DECREF(value);
506 goto error;
508 i++;
511 return result_list;
513 error:
514 Py_DECREF(result_list);
515 return NULL;
518 static PyMethodDef poll_methods[] = {
519 {"register", (PyCFunction)poll_register,
520 METH_VARARGS, poll_register_doc},
521 {"unregister", (PyCFunction)poll_unregister,
522 METH_VARARGS, poll_unregister_doc},
523 {"poll", (PyCFunction)poll_poll,
524 METH_VARARGS, poll_poll_doc},
525 {NULL, NULL} /* sentinel */
528 static pollObject *
529 newPollObject(void)
531 pollObject *self;
532 self = PyObject_New(pollObject, &poll_Type);
533 if (self == NULL)
534 return NULL;
535 /* ufd_uptodate is a Boolean, denoting whether the
536 array pointed to by ufds matches the contents of the dictionary. */
537 self->ufd_uptodate = 0;
538 self->ufds = NULL;
539 self->dict = PyDict_New();
540 if (self->dict == NULL) {
541 Py_DECREF(self);
542 return NULL;
544 return self;
547 static void
548 poll_dealloc(pollObject *self)
550 if (self->ufds != NULL)
551 PyMem_DEL(self->ufds);
552 Py_XDECREF(self->dict);
553 PyObject_Del(self);
556 static PyObject *
557 poll_getattr(pollObject *self, char *name)
559 return Py_FindMethod(poll_methods, (PyObject *)self, name);
562 statichere PyTypeObject poll_Type = {
563 /* The ob_type field must be initialized in the module init function
564 * to be portable to Windows without using C++. */
565 PyObject_HEAD_INIT(NULL)
566 0, /*ob_size*/
567 "select.poll", /*tp_name*/
568 sizeof(pollObject), /*tp_basicsize*/
569 0, /*tp_itemsize*/
570 /* methods */
571 (destructor)poll_dealloc, /*tp_dealloc*/
572 0, /*tp_print*/
573 (getattrfunc)poll_getattr, /*tp_getattr*/
574 0, /*tp_setattr*/
575 0, /*tp_compare*/
576 0, /*tp_repr*/
577 0, /*tp_as_number*/
578 0, /*tp_as_sequence*/
579 0, /*tp_as_mapping*/
580 0, /*tp_hash*/
583 static char poll_doc[] =
584 "Returns a polling object, which supports registering and\n\
585 unregistering file descriptors, and then polling them for I/O events.";
587 static PyObject *
588 select_poll(PyObject *self, PyObject *args)
590 pollObject *rv;
592 if (!PyArg_ParseTuple(args, ":poll"))
593 return NULL;
594 rv = newPollObject();
595 if ( rv == NULL )
596 return NULL;
597 return (PyObject *)rv;
599 #endif /* HAVE_POLL */
601 static char select_doc[] =
602 "select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
604 Wait until one or more file descriptors are ready for some kind of I/O.\n\
605 The first three arguments are lists of file descriptors to be waited for:\n\
606 rlist -- wait until ready for reading\n\
607 wlist -- wait until ready for writing\n\
608 xlist -- wait for an ``exceptional condition''\n\
609 If only one kind of condition is required, pass [] for the other lists.\n\
610 A file descriptor is either a socket or file object, or a small integer\n\
611 gotten from a fileno() method call on one of those.\n\
613 The optional 4th argument specifies a timeout in seconds; it may be\n\
614 a floating point number to specify fractions of seconds. If it is absent\n\
615 or None, the call will never time out.\n\
617 The return value is a tuple of three lists corresponding to the first three\n\
618 arguments; each contains the subset of the corresponding file descriptors\n\
619 that are ready.\n\
621 *** IMPORTANT NOTICE ***\n\
622 On Windows, only sockets are supported; on Unix, all file descriptors.";
624 static PyMethodDef select_methods[] = {
625 {"select", select_select, METH_VARARGS, select_doc},
626 #ifdef HAVE_POLL
627 {"poll", select_poll, METH_VARARGS, poll_doc},
628 #endif /* HAVE_POLL */
629 {0, 0}, /* sentinel */
632 static char module_doc[] =
633 "This module supports asynchronous I/O on multiple file descriptors.\n\
635 *** IMPORTANT NOTICE ***\n\
636 On Windows, only sockets are supported; on Unix, all file descriptors.";
639 * Convenience routine to export an integer value.
640 * For simplicity, errors (which are unlikely anyway) are ignored.
643 static void
644 insint(PyObject *d, char *name, int value)
646 PyObject *v = PyInt_FromLong((long) value);
647 if (v == NULL) {
648 /* Don't bother reporting this error */
649 PyErr_Clear();
651 else {
652 PyDict_SetItemString(d, name, v);
653 Py_DECREF(v);
657 DL_EXPORT(void)
658 initselect(void)
660 PyObject *m, *d;
661 m = Py_InitModule3("select", select_methods, module_doc);
662 d = PyModule_GetDict(m);
663 SelectError = PyErr_NewException("select.error", NULL, NULL);
664 PyDict_SetItemString(d, "error", SelectError);
665 #ifdef HAVE_POLL
666 poll_Type.ob_type = &PyType_Type;
667 insint(d, "POLLIN", POLLIN);
668 insint(d, "POLLPRI", POLLPRI);
669 insint(d, "POLLOUT", POLLOUT);
670 insint(d, "POLLERR", POLLERR);
671 insint(d, "POLLHUP", POLLHUP);
672 insint(d, "POLLNVAL", POLLNVAL);
674 #ifdef POLLRDNORM
675 insint(d, "POLLRDNORM", POLLRDNORM);
676 #endif
677 #ifdef POLLRDBAND
678 insint(d, "POLLRDBAND", POLLRDBAND);
679 #endif
680 #ifdef POLLWRNORM
681 insint(d, "POLLWRNORM", POLLWRNORM);
682 #endif
683 #ifdef POLLWRBAND
684 insint(d, "POLLWRBAND", POLLWRBAND);
685 #endif
686 #ifdef POLLMSG
687 insint(d, "POLLMSG", POLLMSG);
688 #endif
689 #endif /* HAVE_POLL */