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
12 /* Perform runtime testing for a broken poll on OSX to make it easier
13 * to use the same binary on multiple releases of the OS.
15 #undef HAVE_BROKEN_POLL
18 /* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
19 64 is too small (too many people have bumped into that limit).
21 Users who want even more than the boosted limit should #define
22 FD_SETSIZE higher before this; e.g., via compiler /D switch.
24 #if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
25 #define FD_SETSIZE 512
28 #if defined(HAVE_POLL_H)
30 #elif defined(HAVE_SYS_POLL_H)
35 /* This is missing from unistd.h */
36 extern void bzero(void *, int);
39 #ifndef DONT_HAVE_SYS_TYPES_H
40 #include <sys/types.h>
43 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
52 #include <net/socket.h>
60 static PyObject
*SelectError
;
62 /* list of Python objects and their file descriptor */
64 PyObject
*obj
; /* owned reference */
66 int sentinel
; /* -1 == sentinel */
70 reap_obj(pylist fd2obj
[FD_SETSIZE
+ 1])
73 for (i
= 0; i
< FD_SETSIZE
+ 1 && fd2obj
[i
].sentinel
>= 0; i
++) {
74 Py_XDECREF(fd2obj
[i
].obj
);
77 fd2obj
[0].sentinel
= -1;
81 /* returns -1 and sets the Python exception if an error occurred, otherwise
85 seq2set(PyObject
*seq
, fd_set
*set
, pylist fd2obj
[FD_SETSIZE
+ 1])
91 PyObject
* fast_seq
= NULL
;
94 fd2obj
[0].obj
= (PyObject
*)0; /* set list to zero size */
97 fast_seq
=PySequence_Fast(seq
, "arguments 1-3 must be sequences");
101 len
= PySequence_Fast_GET_SIZE(fast_seq
);
103 for (i
= 0; i
< len
; i
++) {
106 /* any intervening fileno() calls could decr this refcnt */
107 if (!(o
= PySequence_Fast_GET_ITEM(fast_seq
, i
)))
111 v
= PyObject_AsFileDescriptor( o
);
112 if (v
== -1) goto finally
;
114 #if defined(_MSC_VER)
115 max
= 0; /* not used for Win32 */
116 #else /* !_MSC_VER */
117 if (v
< 0 || v
>= FD_SETSIZE
) {
118 PyErr_SetString(PyExc_ValueError
,
119 "filedescriptor out of range in select()");
124 #endif /* _MSC_VER */
127 /* add object and its file descriptor to the list */
128 if (index
>= FD_SETSIZE
) {
129 PyErr_SetString(PyExc_ValueError
,
130 "too many file descriptors in select()");
133 fd2obj
[index
].obj
= o
;
134 fd2obj
[index
].fd
= v
;
135 fd2obj
[index
].sentinel
= 0;
136 fd2obj
[++index
].sentinel
= -1;
147 /* returns NULL and sets the Python exception if an error occurred */
149 set2list(fd_set
*set
, pylist fd2obj
[FD_SETSIZE
+ 1])
155 for (j
= 0; fd2obj
[j
].sentinel
>= 0; j
++) {
156 if (FD_ISSET(fd2obj
[j
].fd
, set
))
159 list
= PyList_New(count
);
164 for (j
= 0; fd2obj
[j
].sentinel
>= 0; j
++) {
166 if (FD_ISSET(fd
, set
)) {
168 if (fd
> FD_SETSIZE
) {
169 PyErr_SetString(PyExc_SystemError
,
170 "filedescriptor out of range returned in select()");
175 fd2obj
[j
].obj
= NULL
;
176 /* transfer ownership */
177 if (PyList_SetItem(list
, i
, o
) < 0)
189 #undef SELECT_USES_HEAP
190 #if FD_SETSIZE > 1024
191 #define SELECT_USES_HEAP
192 #endif /* FD_SETSIZE > 1024 */
195 select_select(PyObject
*self
, PyObject
*args
)
197 #ifdef SELECT_USES_HEAP
198 pylist
*rfd2obj
, *wfd2obj
, *efd2obj
;
199 #else /* !SELECT_USES_HEAP */
200 /* XXX: All this should probably be implemented as follows:
201 * - find the highest descriptor we're interested in
204 * See: Stevens, APitUE, $12.5.1
206 pylist rfd2obj
[FD_SETSIZE
+ 1];
207 pylist wfd2obj
[FD_SETSIZE
+ 1];
208 pylist efd2obj
[FD_SETSIZE
+ 1];
209 #endif /* SELECT_USES_HEAP */
210 PyObject
*ifdlist
, *ofdlist
, *efdlist
;
211 PyObject
*ret
= NULL
;
212 PyObject
*tout
= Py_None
;
213 fd_set ifdset
, ofdset
, efdset
;
215 struct timeval tv
, *tvp
;
217 int imax
, omax
, emax
, max
;
220 /* convert arguments */
221 if (!PyArg_UnpackTuple(args
, "select", 3, 4,
222 &ifdlist
, &ofdlist
, &efdlist
, &tout
))
226 tvp
= (struct timeval
*)0;
227 else if (!PyNumber_Check(tout
)) {
228 PyErr_SetString(PyExc_TypeError
,
229 "timeout must be a float or None");
233 timeout
= PyFloat_AsDouble(tout
);
234 if (timeout
== -1 && PyErr_Occurred())
236 if (timeout
> (double)LONG_MAX
) {
237 PyErr_SetString(PyExc_OverflowError
,
238 "timeout period too long");
241 seconds
= (long)timeout
;
242 timeout
= timeout
- (double)seconds
;
244 tv
.tv_usec
= (long)(timeout
*1000000.0);
249 #ifdef SELECT_USES_HEAP
250 /* Allocate memory for the lists */
251 rfd2obj
= PyMem_NEW(pylist
, FD_SETSIZE
+ 1);
252 wfd2obj
= PyMem_NEW(pylist
, FD_SETSIZE
+ 1);
253 efd2obj
= PyMem_NEW(pylist
, FD_SETSIZE
+ 1);
254 if (rfd2obj
== NULL
|| wfd2obj
== NULL
|| efd2obj
== NULL
) {
255 if (rfd2obj
) PyMem_DEL(rfd2obj
);
256 if (wfd2obj
) PyMem_DEL(wfd2obj
);
257 if (efd2obj
) PyMem_DEL(efd2obj
);
258 return PyErr_NoMemory();
260 #endif /* SELECT_USES_HEAP */
261 /* Convert sequences to fd_sets, and get maximum fd number
262 * propagates the Python exception set in seq2set()
264 rfd2obj
[0].sentinel
= -1;
265 wfd2obj
[0].sentinel
= -1;
266 efd2obj
[0].sentinel
= -1;
267 if ((imax
=seq2set(ifdlist
, &ifdset
, rfd2obj
)) < 0)
269 if ((omax
=seq2set(ofdlist
, &ofdset
, wfd2obj
)) < 0)
271 if ((emax
=seq2set(efdlist
, &efdset
, efd2obj
)) < 0)
274 if (omax
> max
) max
= omax
;
275 if (emax
> max
) max
= emax
;
277 Py_BEGIN_ALLOW_THREADS
278 n
= select(max
, &ifdset
, &ofdset
, &efdset
, tvp
);
282 if (n
== SOCKET_ERROR
) {
283 PyErr_SetExcFromWindowsErr(SelectError
, WSAGetLastError());
287 PyErr_SetFromErrno(SelectError
);
292 ifdlist
= PyList_New(0);
294 ret
= PyTuple_Pack(3, ifdlist
, ifdlist
, ifdlist
);
299 /* any of these three calls can raise an exception. it's more
300 convenient to test for this after all three calls... but
303 ifdlist
= set2list(&ifdset
, rfd2obj
);
304 ofdlist
= set2list(&ofdset
, wfd2obj
);
305 efdlist
= set2list(&efdset
, efd2obj
);
306 if (PyErr_Occurred())
309 ret
= PyTuple_Pack(3, ifdlist
, ofdlist
, efdlist
);
320 #ifdef SELECT_USES_HEAP
324 #endif /* SELECT_USES_HEAP */
328 #if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
341 static PyTypeObject poll_Type
;
343 /* Update the malloc'ed array of pollfds to match the dictionary
344 contained within a pollObject. Return 1 on success, 0 on an error.
348 update_ufd_array(pollObject
*self
)
351 PyObject
*key
, *value
;
353 self
->ufd_len
= PyDict_Size(self
->dict
);
354 PyMem_Resize(self
->ufds
, struct pollfd
, self
->ufd_len
);
355 if (self
->ufds
== NULL
) {
361 while (PyDict_Next(self
->dict
, &pos
, &key
, &value
)) {
362 self
->ufds
[i
].fd
= PyInt_AsLong(key
);
363 self
->ufds
[i
].events
= (short)PyInt_AsLong(value
);
366 self
->ufd_uptodate
= 1;
370 PyDoc_STRVAR(poll_register_doc
,
371 "register(fd [, eventmask] ) -> None\n\n\
372 Register a file descriptor with the polling object.\n\
373 fd -- either an integer, or an object with a fileno() method returning an\n\
375 events -- an optional bitmask describing the type of events to check for");
378 poll_register(pollObject
*self
, PyObject
*args
)
380 PyObject
*o
, *key
, *value
;
381 int fd
, events
= POLLIN
| POLLPRI
| POLLOUT
;
384 if (!PyArg_ParseTuple(args
, "O|i:register", &o
, &events
)) {
388 fd
= PyObject_AsFileDescriptor(o
);
389 if (fd
== -1) return NULL
;
391 /* Add entry to the internal dictionary: the key is the
392 file descriptor, and the value is the event mask. */
393 key
= PyInt_FromLong(fd
);
396 value
= PyInt_FromLong(events
);
401 err
= PyDict_SetItem(self
->dict
, key
, value
);
407 self
->ufd_uptodate
= 0;
413 PyDoc_STRVAR(poll_unregister_doc
,
414 "unregister(fd) -> None\n\n\
415 Remove a file descriptor being tracked by the polling object.");
418 poll_unregister(pollObject
*self
, PyObject
*o
)
423 fd
= PyObject_AsFileDescriptor( o
);
427 /* Check whether the fd is already in the array */
428 key
= PyInt_FromLong(fd
);
432 if (PyDict_DelItem(self
->dict
, key
) == -1) {
434 /* This will simply raise the KeyError set by PyDict_DelItem
435 if the file descriptor isn't registered. */
440 self
->ufd_uptodate
= 0;
446 PyDoc_STRVAR(poll_poll_doc
,
447 "poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
448 Polls the set of registered file descriptors, returning a list containing \n\
449 any descriptors that have events or errors to report.");
452 poll_poll(pollObject
*self
, PyObject
*args
)
454 PyObject
*result_list
= NULL
, *tout
= NULL
;
455 int timeout
= 0, poll_result
, i
, j
;
456 PyObject
*value
= NULL
, *num
= NULL
;
458 if (!PyArg_UnpackTuple(args
, "poll", 0, 1, &tout
)) {
462 /* Check values for timeout */
463 if (tout
== NULL
|| tout
== Py_None
)
465 else if (!PyNumber_Check(tout
)) {
466 PyErr_SetString(PyExc_TypeError
,
467 "timeout must be an integer or None");
471 tout
= PyNumber_Int(tout
);
474 timeout
= PyInt_AsLong(tout
);
476 if (timeout
== -1 && PyErr_Occurred())
480 /* Ensure the ufd array is up to date */
481 if (!self
->ufd_uptodate
)
482 if (update_ufd_array(self
) == 0)
486 Py_BEGIN_ALLOW_THREADS
;
487 poll_result
= poll(self
->ufds
, self
->ufd_len
, timeout
);
488 Py_END_ALLOW_THREADS
;
490 if (poll_result
< 0) {
491 PyErr_SetFromErrno(SelectError
);
495 /* build the result list */
497 result_list
= PyList_New(poll_result
);
501 for (i
= 0, j
= 0; j
< poll_result
; j
++) {
502 /* skip to the next fired descriptor */
503 while (!self
->ufds
[i
].revents
) {
506 /* if we hit a NULL return, set value to NULL
507 and break out of loop; code at end will
508 clean up result_list */
509 value
= PyTuple_New(2);
512 num
= PyInt_FromLong(self
->ufds
[i
].fd
);
517 PyTuple_SET_ITEM(value
, 0, num
);
519 /* The &0xffff is a workaround for AIX. 'revents'
520 is a 16-bit short, and IBM assigned POLLNVAL
521 to be 0x8000, so the conversion to int results
522 in a negative number. See SF bug #923315. */
523 num
= PyInt_FromLong(self
->ufds
[i
].revents
& 0xffff);
528 PyTuple_SET_ITEM(value
, 1, num
);
529 if ((PyList_SetItem(result_list
, j
, value
)) == -1) {
539 Py_DECREF(result_list
);
543 static PyMethodDef poll_methods
[] = {
544 {"register", (PyCFunction
)poll_register
,
545 METH_VARARGS
, poll_register_doc
},
546 {"unregister", (PyCFunction
)poll_unregister
,
547 METH_O
, poll_unregister_doc
},
548 {"poll", (PyCFunction
)poll_poll
,
549 METH_VARARGS
, poll_poll_doc
},
550 {NULL
, NULL
} /* sentinel */
557 self
= PyObject_New(pollObject
, &poll_Type
);
560 /* ufd_uptodate is a Boolean, denoting whether the
561 array pointed to by ufds matches the contents of the dictionary. */
562 self
->ufd_uptodate
= 0;
564 self
->dict
= PyDict_New();
565 if (self
->dict
== NULL
) {
573 poll_dealloc(pollObject
*self
)
575 if (self
->ufds
!= NULL
)
576 PyMem_DEL(self
->ufds
);
577 Py_XDECREF(self
->dict
);
582 poll_getattr(pollObject
*self
, char *name
)
584 return Py_FindMethod(poll_methods
, (PyObject
*)self
, name
);
587 static PyTypeObject poll_Type
= {
588 /* The ob_type field must be initialized in the module init function
589 * to be portable to Windows without using C++. */
590 PyObject_HEAD_INIT(NULL
)
592 "select.poll", /*tp_name*/
593 sizeof(pollObject
), /*tp_basicsize*/
596 (destructor
)poll_dealloc
, /*tp_dealloc*/
598 (getattrfunc
)poll_getattr
, /*tp_getattr*/
603 0, /*tp_as_sequence*/
608 PyDoc_STRVAR(poll_doc
,
609 "Returns a polling object, which supports registering and\n\
610 unregistering file descriptors, and then polling them for I/O events.");
613 select_poll(PyObject
*self
, PyObject
*unused
)
615 return (PyObject
*)newPollObject();
620 * On some systems poll() sets errno on invalid file descriptors. We test
621 * for this at runtime because this bug may be fixed or introduced between
624 static int select_have_broken_poll(void)
629 struct pollfd poll_struct
= { 0, POLLIN
|POLLPRI
|POLLOUT
, 0 };
631 /* Create a file descriptor to make invalid */
632 if (pipe(filedes
) < 0) {
635 poll_struct
.fd
= filedes
[0];
638 poll_test
= poll(&poll_struct
, 1, 0);
641 } else if (poll_test
== 0 && poll_struct
.revents
!= POLLNVAL
) {
646 #endif /* __APPLE__ */
648 #endif /* HAVE_POLL */
650 PyDoc_STRVAR(select_doc
,
651 "select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
653 Wait until one or more file descriptors are ready for some kind of I/O.\n\
654 The first three arguments are sequences of file descriptors to be waited for:\n\
655 rlist -- wait until ready for reading\n\
656 wlist -- wait until ready for writing\n\
657 xlist -- wait for an ``exceptional condition''\n\
658 If only one kind of condition is required, pass [] for the other lists.\n\
659 A file descriptor is either a socket or file object, or a small integer\n\
660 gotten from a fileno() method call on one of those.\n\
662 The optional 4th argument specifies a timeout in seconds; it may be\n\
663 a floating point number to specify fractions of seconds. If it is absent\n\
664 or None, the call will never time out.\n\
666 The return value is a tuple of three lists corresponding to the first three\n\
667 arguments; each contains the subset of the corresponding file descriptors\n\
670 *** IMPORTANT NOTICE ***\n\
671 On Windows, only sockets are supported; on Unix, all file descriptors.");
673 static PyMethodDef select_methods
[] = {
674 {"select", select_select
, METH_VARARGS
, select_doc
},
675 #if defined(HAVE_POLL)
676 {"poll", select_poll
, METH_NOARGS
, poll_doc
},
677 #endif /* HAVE_POLL */
678 {0, 0}, /* sentinel */
681 PyDoc_STRVAR(module_doc
,
682 "This module supports asynchronous I/O on multiple file descriptors.\n\
684 *** IMPORTANT NOTICE ***\n\
685 On Windows, only sockets are supported; on Unix, all file descriptors.");
691 m
= Py_InitModule3("select", select_methods
, module_doc
);
695 SelectError
= PyErr_NewException("select.error", NULL
, NULL
);
696 Py_INCREF(SelectError
);
697 PyModule_AddObject(m
, "error", SelectError
);
698 #if defined(HAVE_POLL)
701 if (select_have_broken_poll()) {
702 if (PyObject_DelAttrString(m
, "poll") == -1) {
709 poll_Type
.ob_type
= &PyType_Type
;
710 PyModule_AddIntConstant(m
, "POLLIN", POLLIN
);
711 PyModule_AddIntConstant(m
, "POLLPRI", POLLPRI
);
712 PyModule_AddIntConstant(m
, "POLLOUT", POLLOUT
);
713 PyModule_AddIntConstant(m
, "POLLERR", POLLERR
);
714 PyModule_AddIntConstant(m
, "POLLHUP", POLLHUP
);
715 PyModule_AddIntConstant(m
, "POLLNVAL", POLLNVAL
);
718 PyModule_AddIntConstant(m
, "POLLRDNORM", POLLRDNORM
);
721 PyModule_AddIntConstant(m
, "POLLRDBAND", POLLRDBAND
);
724 PyModule_AddIntConstant(m
, "POLLWRNORM", POLLWRNORM
);
727 PyModule_AddIntConstant(m
, "POLLWRBAND", POLLWRBAND
);
730 PyModule_AddIntConstant(m
, "POLLMSG", POLLMSG
);
733 #endif /* HAVE_POLL */