blob: 81c9e3cd98478261f63f6dcd480584cdbecbca66 [file] [log] [blame]
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00001/* select - Module containing unix select(2) call.
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002 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.
Guido van Rossumbcc20741998-08-04 22:53:56 +00005 Under BeOS, we suffer the same dichotomy as Win32; sockets can be anything
6 >= 0.
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00007*/
Guido van Rossumed233a51992-06-23 09:07:03 +00008
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00009#include "Python.h"
Guido van Rossumed233a51992-06-23 09:07:03 +000010
Tim Petersd92dfe02000-12-12 01:18:41 +000011/* 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.
16*/
17#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
18#define FD_SETSIZE 512
19#endif
20
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000021#if defined(HAVE_POLL_H)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000022#include <poll.h>
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000023#elif defined(HAVE_SYS_POLL_H)
24#include <sys/poll.h>
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000025#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000026
Guido van Rossum37273171996-12-09 18:47:43 +000027#ifdef __sgi
28/* This is missing from unistd.h */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000029extern void bzero(void *, int);
Guido van Rossum37273171996-12-09 18:47:43 +000030#endif
31
Guido van Rossumff7e83d1999-08-27 20:39:37 +000032#ifndef DONT_HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000033#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000034#endif
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000035
Andrew MacIntyre7bf68332002-03-03 02:59:16 +000036#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000037#include <sys/time.h>
38#include <utils.h>
39#endif
40
Guido van Rossum6f489d91996-06-28 20:15:15 +000041#ifdef MS_WINDOWS
Thomas Heller7bdabe62002-09-24 17:03:26 +000042#include <winsock.h>
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000043#else
Guido van Rossumbcc20741998-08-04 22:53:56 +000044#ifdef __BEOS__
45#include <net/socket.h>
46#define SOCKET int
47#else
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000048#define SOCKET int
49#endif
Guido van Rossumbcc20741998-08-04 22:53:56 +000050#endif
Guido van Rossumed233a51992-06-23 09:07:03 +000051
Guido van Rossum1ca8bb32001-03-02 06:28:17 +000052
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000053static PyObject *SelectError;
Guido van Rossumed233a51992-06-23 09:07:03 +000054
Barry Warsawc1cb3601996-12-12 22:16:21 +000055/* list of Python objects and their file descriptor */
56typedef struct {
57 PyObject *obj; /* owned reference */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000058 SOCKET fd;
Barry Warsawc1cb3601996-12-12 22:16:21 +000059 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000060} pylist;
61
Barry Warsawc1cb3601996-12-12 22:16:21 +000062static void
Tim Peters4b046c22001-08-16 21:59:46 +000063reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +000064{
65 int i;
Tim Peters4b046c22001-08-16 21:59:46 +000066 for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
Barry Warsawc1cb3601996-12-12 22:16:21 +000067 Py_XDECREF(fd2obj[i].obj);
68 fd2obj[i].obj = NULL;
69 }
70 fd2obj[0].sentinel = -1;
71}
72
73
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000074/* returns -1 and sets the Python exception if an error occurred, otherwise
75 returns a number >= 0
76*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000077static int
Brett Cannon62dba4c2003-09-10 19:37:42 +000078seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +000079{
Barry Warsawc1cb3601996-12-12 22:16:21 +000080 int i;
81 int max = -1;
82 int index = 0;
Brett Cannon62dba4c2003-09-10 19:37:42 +000083 int len = -1;
84 PyObject* fast_seq = NULL;
Barry Warsawc1cb3601996-12-12 22:16:21 +000085 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000086
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000087 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000088 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000089
Brett Cannon62dba4c2003-09-10 19:37:42 +000090 fast_seq=PySequence_Fast(seq, "arguments 1-3 must be sequences");
91 if (!fast_seq)
92 return -1;
93
94 len = PySequence_Fast_GET_SIZE(fast_seq);
95
Barry Warsawc1cb3601996-12-12 22:16:21 +000096 for (i = 0; i < len; i++) {
Barry Warsawc1cb3601996-12-12 22:16:21 +000097 SOCKET v;
98
99 /* any intervening fileno() calls could decr this refcnt */
Brett Cannon62dba4c2003-09-10 19:37:42 +0000100 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Barry Warsaw529fcfe1996-12-16 18:15:34 +0000101 return -1;
Barry Warsaw24c4b3d1996-12-13 23:22:42 +0000102
Barry Warsawc1cb3601996-12-12 22:16:21 +0000103 Py_INCREF(o);
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +0000104 v = PyObject_AsFileDescriptor( o );
105 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000106
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000107#if defined(_MSC_VER)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000108 max = 0; /* not used for Win32 */
109#else /* !_MSC_VER */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000110 if (v < 0 || v >= FD_SETSIZE) {
Barry Warsawc1cb3601996-12-12 22:16:21 +0000111 PyErr_SetString(PyExc_ValueError,
112 "filedescriptor out of range in select()");
113 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000114 }
115 if (v > max)
116 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000117#endif /* _MSC_VER */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000118 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000119
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000120 /* add object and its file descriptor to the list */
121 if (index >= FD_SETSIZE) {
Barry Warsawc1cb3601996-12-12 22:16:21 +0000122 PyErr_SetString(PyExc_ValueError,
123 "too many file descriptors in select()");
124 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000125 }
126 fd2obj[index].obj = o;
127 fd2obj[index].fd = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000128 fd2obj[index].sentinel = 0;
129 fd2obj[++index].sentinel = -1;
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000130 }
Brett Cannon62dba4c2003-09-10 19:37:42 +0000131 Py_DECREF(fast_seq);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000132 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000133
134 finally:
135 Py_XDECREF(o);
Brett Cannon62dba4c2003-09-10 19:37:42 +0000136 Py_DECREF(fast_seq);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000137 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000138}
139
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000140/* returns NULL and sets the Python exception if an error occurred */
141static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000142set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000143{
Barry Warsawc1cb3601996-12-12 22:16:21 +0000144 int i, j, count=0;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000145 PyObject *list, *o;
146 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000147
Barry Warsawc1cb3601996-12-12 22:16:21 +0000148 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000149 if (FD_ISSET(fd2obj[j].fd, set))
Barry Warsawc1cb3601996-12-12 22:16:21 +0000150 count++;
151 }
152 list = PyList_New(count);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000153 if (!list)
154 return NULL;
155
Barry Warsawc1cb3601996-12-12 22:16:21 +0000156 i = 0;
157 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000158 fd = fd2obj[j].fd;
159 if (FD_ISSET(fd, set)) {
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000160#ifndef _MSC_VER
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000161 if (fd > FD_SETSIZE) {
162 PyErr_SetString(PyExc_SystemError,
163 "filedescriptor out of range returned in select()");
Barry Warsawc1cb3601996-12-12 22:16:21 +0000164 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000165 }
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000166#endif
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000167 o = fd2obj[j].obj;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000168 fd2obj[j].obj = NULL;
169 /* transfer ownership */
170 if (PyList_SetItem(list, i, o) < 0)
171 goto finally;
172
173 i++;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000174 }
175 }
176 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000177 finally:
178 Py_DECREF(list);
179 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000180}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000181
Barry Warsawb44740f2001-08-16 16:52:59 +0000182#undef SELECT_USES_HEAP
183#if FD_SETSIZE > 1024
184#define SELECT_USES_HEAP
185#endif /* FD_SETSIZE > 1024 */
186
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000187static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000188select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000189{
Barry Warsawb44740f2001-08-16 16:52:59 +0000190#ifdef SELECT_USES_HEAP
Guido van Rossumd20781b1998-07-02 02:53:36 +0000191 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000192#else /* !SELECT_USES_HEAP */
Tim Peters4b046c22001-08-16 21:59:46 +0000193 /* XXX: All this should probably be implemented as follows:
Barry Warsawb44740f2001-08-16 16:52:59 +0000194 * - find the highest descriptor we're interested in
195 * - add one
196 * - that's the size
197 * See: Stevens, APitUE, $12.5.1
198 */
Tim Peters4b046c22001-08-16 21:59:46 +0000199 pylist rfd2obj[FD_SETSIZE + 1];
200 pylist wfd2obj[FD_SETSIZE + 1];
201 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000202#endif /* SELECT_USES_HEAP */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000203 PyObject *ifdlist, *ofdlist, *efdlist;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000204 PyObject *ret = NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000205 PyObject *tout = Py_None;
206 fd_set ifdset, ofdset, efdset;
207 double timeout;
208 struct timeval tv, *tvp;
Guido van Rossum3262e162000-06-28 21:18:13 +0000209 long seconds;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000210 int imax, omax, emax, max;
211 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000212
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000213 /* convert arguments */
Guido van Rossum43713e52000-02-29 13:59:29 +0000214 if (!PyArg_ParseTuple(args, "OOO|O:select",
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000215 &ifdlist, &ofdlist, &efdlist, &tout))
216 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000217
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000218 if (tout == Py_None)
219 tvp = (struct timeval *)0;
Neal Norwitz77c72bb2002-07-28 15:12:10 +0000220 else if (!PyNumber_Check(tout)) {
Barry Warsawc1cb3601996-12-12 22:16:21 +0000221 PyErr_SetString(PyExc_TypeError,
222 "timeout must be a float or None");
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000223 return NULL;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000224 }
Guido van Rossumc7a22701993-11-01 16:27:16 +0000225 else {
Neil Schemenauer47ec6c02002-11-18 16:02:29 +0000226 timeout = PyFloat_AsDouble(tout);
227 if (timeout == -1 && PyErr_Occurred())
Neal Norwitz77c72bb2002-07-28 15:12:10 +0000228 return NULL;
Guido van Rossum3262e162000-06-28 21:18:13 +0000229 if (timeout > (double)LONG_MAX) {
Barry Warsaw2f704552001-08-16 16:55:10 +0000230 PyErr_SetString(PyExc_OverflowError,
231 "timeout period too long");
Guido van Rossum3262e162000-06-28 21:18:13 +0000232 return NULL;
233 }
234 seconds = (long)timeout;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000235 timeout = timeout - (double)seconds;
236 tv.tv_sec = seconds;
Guido van Rossum3262e162000-06-28 21:18:13 +0000237 tv.tv_usec = (long)(timeout*1000000.0);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000238 tvp = &tv;
Guido van Rossumc7a22701993-11-01 16:27:16 +0000239 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000240
Guido van Rossumed233a51992-06-23 09:07:03 +0000241
Barry Warsawb44740f2001-08-16 16:52:59 +0000242#ifdef SELECT_USES_HEAP
Guido van Rossumd20781b1998-07-02 02:53:36 +0000243 /* Allocate memory for the lists */
Tim Peters4b046c22001-08-16 21:59:46 +0000244 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
245 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
246 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
Guido van Rossumd20781b1998-07-02 02:53:36 +0000247 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
Guido van Rossumb18618d2000-05-03 23:44:39 +0000248 if (rfd2obj) PyMem_DEL(rfd2obj);
249 if (wfd2obj) PyMem_DEL(wfd2obj);
250 if (efd2obj) PyMem_DEL(efd2obj);
Tim Peters5f322d32003-02-11 17:18:58 +0000251 return PyErr_NoMemory();
Guido van Rossumd20781b1998-07-02 02:53:36 +0000252 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000253#endif /* SELECT_USES_HEAP */
Brett Cannon62dba4c2003-09-10 19:37:42 +0000254 /* Convert sequences to fd_sets, and get maximum fd number
255 * propagates the Python exception set in seq2set()
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000256 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000257 rfd2obj[0].sentinel = -1;
258 wfd2obj[0].sentinel = -1;
259 efd2obj[0].sentinel = -1;
Brett Cannon62dba4c2003-09-10 19:37:42 +0000260 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000261 goto finally;
Brett Cannon62dba4c2003-09-10 19:37:42 +0000262 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000263 goto finally;
Brett Cannon62dba4c2003-09-10 19:37:42 +0000264 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000265 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000266 max = imax;
267 if (omax > max) max = omax;
268 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000269
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000270 Py_BEGIN_ALLOW_THREADS
271 n = select(max, &ifdset, &ofdset, &efdset, tvp);
272 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000273
Thomas Heller106f4c72002-09-24 16:51:00 +0000274#ifdef MS_WINDOWS
275 if (n == SOCKET_ERROR) {
276 PyErr_SetExcFromWindowsErr(SelectError, WSAGetLastError());
277 }
278#else
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000279 if (n < 0) {
280 PyErr_SetFromErrno(SelectError);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000281 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000282#endif
Barry Warsawc1cb3601996-12-12 22:16:21 +0000283 else if (n == 0) {
284 /* optimization */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000285 ifdlist = PyList_New(0);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000286 if (ifdlist) {
Raymond Hettinger8ae46892003-10-12 19:09:37 +0000287 ret = PyTuple_Pack(3, ifdlist, ifdlist, ifdlist);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000288 Py_DECREF(ifdlist);
289 }
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000290 }
Barry Warsawc1cb3601996-12-12 22:16:21 +0000291 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?
295 */
296 ifdlist = set2list(&ifdset, rfd2obj);
297 ofdlist = set2list(&ofdset, wfd2obj);
298 efdlist = set2list(&efdset, efd2obj);
299 if (PyErr_Occurred())
300 ret = NULL;
301 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +0000302 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000303
Barry Warsawc1cb3601996-12-12 22:16:21 +0000304 Py_DECREF(ifdlist);
305 Py_DECREF(ofdlist);
306 Py_DECREF(efdlist);
307 }
308
309 finally:
310 reap_obj(rfd2obj);
311 reap_obj(wfd2obj);
312 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000313#ifdef SELECT_USES_HEAP
Guido van Rossumd20781b1998-07-02 02:53:36 +0000314 PyMem_DEL(rfd2obj);
315 PyMem_DEL(wfd2obj);
316 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000317#endif /* SELECT_USES_HEAP */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000318 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000319}
320
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000321#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000322/*
323 * poll() support
324 */
325
326typedef struct {
327 PyObject_HEAD
328 PyObject *dict;
329 int ufd_uptodate;
330 int ufd_len;
331 struct pollfd *ufds;
332} pollObject;
333
Jeremy Hylton938ace62002-07-17 16:30:39 +0000334static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000335
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.
338*/
339
340static int
341update_ufd_array(pollObject *self)
342{
Fred Drakedff3a372001-07-19 21:29:49 +0000343 int i, pos;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000344 PyObject *key, *value;
345
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;
351 }
352
353 i = pos = 0;
Fred Drakedff3a372001-07-19 21:29:49 +0000354 while (PyDict_Next(self->dict, &pos, &key, &value)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000355 self->ufds[i].fd = PyInt_AsLong(key);
Fred Drakedff3a372001-07-19 21:29:49 +0000356 self->ufds[i].events = (short)PyInt_AsLong(value);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000357 i++;
358 }
359 self->ufd_uptodate = 1;
360 return 1;
361}
362
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000363PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000364"register(fd [, eventmask] ) -> None\n\n\
365Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000366fd -- either an integer, or an object with a fileno() method returning an\n\
367 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000368events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000369
370static PyObject *
371poll_register(pollObject *self, PyObject *args)
372{
373 PyObject *o, *key, *value;
374 int fd, events = POLLIN | POLLPRI | POLLOUT;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000375 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000376
Fred Drake7b87f852001-05-21 03:29:05 +0000377 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000378 return NULL;
379 }
380
381 fd = PyObject_AsFileDescriptor(o);
382 if (fd == -1) return NULL;
383
384 /* Add entry to the internal dictionary: the key is the
385 file descriptor, and the value is the event mask. */
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000386 key = PyInt_FromLong(fd);
387 if (key == NULL)
388 return NULL;
389 value = PyInt_FromLong(events);
390 if (value == NULL) {
391 Py_DECREF(key);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000392 return NULL;
393 }
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000394 err = PyDict_SetItem(self->dict, key, value);
395 Py_DECREF(key);
396 Py_DECREF(value);
397 if (err < 0)
398 return NULL;
399
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000400 self->ufd_uptodate = 0;
401
402 Py_INCREF(Py_None);
403 return Py_None;
404}
405
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000406PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000407"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000408Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000409
410static PyObject *
411poll_unregister(pollObject *self, PyObject *args)
412{
413 PyObject *o, *key;
414 int fd;
415
Fred Drake7b87f852001-05-21 03:29:05 +0000416 if (!PyArg_ParseTuple(args, "O:unregister", &o)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000417 return NULL;
418 }
419
420 fd = PyObject_AsFileDescriptor( o );
421 if (fd == -1)
422 return NULL;
423
424 /* Check whether the fd is already in the array */
425 key = PyInt_FromLong(fd);
426 if (key == NULL)
427 return NULL;
428
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;
434 }
435
436 Py_DECREF(key);
437 self->ufd_uptodate = 0;
438
439 Py_INCREF(Py_None);
440 return Py_None;
441}
442
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000443PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000444"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
445Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000446any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000447
448static PyObject *
449poll_poll(pollObject *self, PyObject *args)
450{
451 PyObject *result_list = NULL, *tout = NULL;
452 int timeout = 0, poll_result, i, j;
453 PyObject *value = NULL, *num = NULL;
454
Fred Drake7b87f852001-05-21 03:29:05 +0000455 if (!PyArg_ParseTuple(args, "|O:poll", &tout)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000456 return NULL;
457 }
458
459 /* Check values for timeout */
460 if (tout == NULL || tout == Py_None)
461 timeout = -1;
Neal Norwitz77c72bb2002-07-28 15:12:10 +0000462 else if (!PyNumber_Check(tout)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000463 PyErr_SetString(PyExc_TypeError,
464 "timeout must be an integer or None");
465 return NULL;
466 }
Neal Norwitz77c72bb2002-07-28 15:12:10 +0000467 else {
468 tout = PyNumber_Int(tout);
469 if (!tout)
470 return NULL;
Walter Dörwald08c4cc42002-11-12 11:42:20 +0000471 timeout = PyInt_AsLong(tout);
Neal Norwitz77c72bb2002-07-28 15:12:10 +0000472 Py_DECREF(tout);
473 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000474
475 /* Ensure the ufd array is up to date */
476 if (!self->ufd_uptodate)
477 if (update_ufd_array(self) == 0)
478 return NULL;
479
480 /* call poll() */
481 Py_BEGIN_ALLOW_THREADS;
482 poll_result = poll(self->ufds, self->ufd_len, timeout);
483 Py_END_ALLOW_THREADS;
484
485 if (poll_result < 0) {
486 PyErr_SetFromErrno(SelectError);
487 return NULL;
488 }
489
490 /* build the result list */
491
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++;
500 }
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;
511 }
512 PyTuple_SET_ITEM(value, 0, num);
513
Andrew M. Kuchlinge5dd1622004-08-07 17:21:27 +0000514 /* The &0xffff is a workaround for AIX. 'revents'
515 is a 16-bit short, and IBM assigned POLLNVAL
516 to be 0x8000, so the conversion to int results
517 in a negative number. See SF bug #923315. */
518 num = PyInt_FromLong(self->ufds[i].revents & 0xffff);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000519 if (num == NULL) {
520 Py_DECREF(value);
521 goto error;
522 }
523 PyTuple_SET_ITEM(value, 1, num);
524 if ((PyList_SetItem(result_list, j, value)) == -1) {
525 Py_DECREF(value);
526 goto error;
527 }
528 i++;
529 }
530 }
531 return result_list;
532
533 error:
534 Py_DECREF(result_list);
535 return NULL;
536}
537
538static PyMethodDef poll_methods[] = {
539 {"register", (PyCFunction)poll_register,
540 METH_VARARGS, poll_register_doc},
541 {"unregister", (PyCFunction)poll_unregister,
542 METH_VARARGS, poll_unregister_doc},
543 {"poll", (PyCFunction)poll_poll,
544 METH_VARARGS, poll_poll_doc},
545 {NULL, NULL} /* sentinel */
546};
547
548static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000549newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000550{
551 pollObject *self;
552 self = PyObject_New(pollObject, &poll_Type);
553 if (self == NULL)
554 return NULL;
555 /* ufd_uptodate is a Boolean, denoting whether the
556 array pointed to by ufds matches the contents of the dictionary. */
557 self->ufd_uptodate = 0;
558 self->ufds = NULL;
559 self->dict = PyDict_New();
560 if (self->dict == NULL) {
561 Py_DECREF(self);
562 return NULL;
563 }
564 return self;
565}
566
567static void
568poll_dealloc(pollObject *self)
569{
570 if (self->ufds != NULL)
571 PyMem_DEL(self->ufds);
572 Py_XDECREF(self->dict);
573 PyObject_Del(self);
574}
575
576static PyObject *
577poll_getattr(pollObject *self, char *name)
578{
579 return Py_FindMethod(poll_methods, (PyObject *)self, name);
580}
581
Tim Peters0c322792002-07-17 16:49:03 +0000582static PyTypeObject poll_Type = {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000583 /* The ob_type field must be initialized in the module init function
584 * to be portable to Windows without using C++. */
585 PyObject_HEAD_INIT(NULL)
586 0, /*ob_size*/
Guido van Rossum14648392001-12-08 18:02:58 +0000587 "select.poll", /*tp_name*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000588 sizeof(pollObject), /*tp_basicsize*/
589 0, /*tp_itemsize*/
590 /* methods */
591 (destructor)poll_dealloc, /*tp_dealloc*/
592 0, /*tp_print*/
593 (getattrfunc)poll_getattr, /*tp_getattr*/
594 0, /*tp_setattr*/
595 0, /*tp_compare*/
596 0, /*tp_repr*/
597 0, /*tp_as_number*/
598 0, /*tp_as_sequence*/
599 0, /*tp_as_mapping*/
600 0, /*tp_hash*/
601};
602
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000603PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000604"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000605unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000606
607static PyObject *
608select_poll(PyObject *self, PyObject *args)
609{
610 pollObject *rv;
611
612 if (!PyArg_ParseTuple(args, ":poll"))
613 return NULL;
614 rv = newPollObject();
615 if ( rv == NULL )
616 return NULL;
617 return (PyObject *)rv;
618}
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000619#endif /* HAVE_POLL && !HAVE_BROKEN_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000620
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000621PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000622"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
623\n\
624Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +0000625The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000626rlist -- wait until ready for reading\n\
627wlist -- wait until ready for writing\n\
628xlist -- wait for an ``exceptional condition''\n\
629If only one kind of condition is required, pass [] for the other lists.\n\
630A file descriptor is either a socket or file object, or a small integer\n\
631gotten from a fileno() method call on one of those.\n\
632\n\
633The optional 4th argument specifies a timeout in seconds; it may be\n\
634a floating point number to specify fractions of seconds. If it is absent\n\
635or None, the call will never time out.\n\
636\n\
637The return value is a tuple of three lists corresponding to the first three\n\
638arguments; each contains the subset of the corresponding file descriptors\n\
639that are ready.\n\
640\n\
641*** IMPORTANT NOTICE ***\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000642On Windows, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000643
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000644static PyMethodDef select_methods[] = {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000645 {"select", select_select, METH_VARARGS, select_doc},
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000646#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000647 {"poll", select_poll, METH_VARARGS, poll_doc},
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000648#endif /* HAVE_POLL && !HAVE_BROKEN_POLL */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000649 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +0000650};
651
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000652PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000653"This module supports asynchronous I/O on multiple file descriptors.\n\
654\n\
655*** IMPORTANT NOTICE ***\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000656On Windows, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +0000657
Mark Hammond62b1ab12002-07-23 06:31:15 +0000658PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000659initselect(void)
Guido van Rossumed233a51992-06-23 09:07:03 +0000660{
Fred Drake4baedc12002-04-01 14:53:37 +0000661 PyObject *m;
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000662 m = Py_InitModule3("select", select_methods, module_doc);
Fred Drake4baedc12002-04-01 14:53:37 +0000663
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000664 SelectError = PyErr_NewException("select.error", NULL, NULL);
Fred Drake4baedc12002-04-01 14:53:37 +0000665 Py_INCREF(SelectError);
666 PyModule_AddObject(m, "error", SelectError);
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000667#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000668 poll_Type.ob_type = &PyType_Type;
Fred Drake4baedc12002-04-01 14:53:37 +0000669 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
670 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
671 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
672 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
673 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
674 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000675
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000676#ifdef POLLRDNORM
Fred Drake4baedc12002-04-01 14:53:37 +0000677 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000678#endif
679#ifdef POLLRDBAND
Fred Drake4baedc12002-04-01 14:53:37 +0000680 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000681#endif
682#ifdef POLLWRNORM
Fred Drake4baedc12002-04-01 14:53:37 +0000683 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000684#endif
685#ifdef POLLWRBAND
Fred Drake4baedc12002-04-01 14:53:37 +0000686 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000687#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +0000688#ifdef POLLMSG
Fred Drake4baedc12002-04-01 14:53:37 +0000689 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +0000690#endif
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000691#endif /* HAVE_POLL && !HAVE_BROKEN_POLL */
Guido van Rossumed233a51992-06-23 09:07:03 +0000692}