blob: e5aa6eb8fcd5ffa05b5394950bfcd302c4d14afa [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
Guido van Rossuma376cc51996-12-05 23:43:35 +000021#ifdef HAVE_UNISTD_H
22#include <unistd.h>
23#endif
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000024#if defined(HAVE_POLL_H)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000025#include <poll.h>
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000026#elif defined(HAVE_SYS_POLL_H)
27#include <sys/poll.h>
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000028#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000029
Guido van Rossum37273171996-12-09 18:47:43 +000030#ifdef __sgi
31/* This is missing from unistd.h */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000032extern void bzero(void *, int);
Guido van Rossum37273171996-12-09 18:47:43 +000033#endif
34
Guido van Rossumff7e83d1999-08-27 20:39:37 +000035#ifndef DONT_HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000036#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000037#endif
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000038
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000039#if defined(PYOS_OS2)
40#include <sys/time.h>
41#include <utils.h>
42#endif
43
Guido van Rossum6f489d91996-06-28 20:15:15 +000044#ifdef MS_WINDOWS
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000045#include <winsock.h>
46#else
Guido van Rossumbcc20741998-08-04 22:53:56 +000047#ifdef __BEOS__
48#include <net/socket.h>
49#define SOCKET int
50#else
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000051#define SOCKET int
52#endif
Guido van Rossumbcc20741998-08-04 22:53:56 +000053#endif
Guido van Rossumed233a51992-06-23 09:07:03 +000054
Guido van Rossum1ca8bb32001-03-02 06:28:17 +000055
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000056static PyObject *SelectError;
Guido van Rossumed233a51992-06-23 09:07:03 +000057
Barry Warsawc1cb3601996-12-12 22:16:21 +000058/* list of Python objects and their file descriptor */
59typedef struct {
60 PyObject *obj; /* owned reference */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000061 SOCKET fd;
Barry Warsawc1cb3601996-12-12 22:16:21 +000062 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000063} pylist;
64
Barry Warsawc1cb3601996-12-12 22:16:21 +000065static void
Tim Peters4b046c22001-08-16 21:59:46 +000066reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +000067{
68 int i;
Tim Peters4b046c22001-08-16 21:59:46 +000069 for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
Barry Warsawc1cb3601996-12-12 22:16:21 +000070 Py_XDECREF(fd2obj[i].obj);
71 fd2obj[i].obj = NULL;
72 }
73 fd2obj[0].sentinel = -1;
74}
75
76
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000077/* returns -1 and sets the Python exception if an error occurred, otherwise
78 returns a number >= 0
79*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000080static int
Tim Peters4b046c22001-08-16 21:59:46 +000081list2set(PyObject *list, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +000082{
Barry Warsawc1cb3601996-12-12 22:16:21 +000083 int i;
84 int max = -1;
85 int index = 0;
86 int len = PyList_Size(list);
87 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000088
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000089 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000090 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000091
92 for (i = 0; i < len; i++) {
Barry Warsawc1cb3601996-12-12 22:16:21 +000093 SOCKET v;
94
95 /* any intervening fileno() calls could decr this refcnt */
Barry Warsaw24c4b3d1996-12-13 23:22:42 +000096 if (!(o = PyList_GetItem(list, i)))
Barry Warsaw529fcfe1996-12-16 18:15:34 +000097 return -1;
Barry Warsaw24c4b3d1996-12-13 23:22:42 +000098
Barry Warsawc1cb3601996-12-12 22:16:21 +000099 Py_INCREF(o);
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +0000100 v = PyObject_AsFileDescriptor( o );
101 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000102
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000103#if defined(_MSC_VER)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000104 max = 0; /* not used for Win32 */
105#else /* !_MSC_VER */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000106 if (v < 0 || v >= FD_SETSIZE) {
Barry Warsawc1cb3601996-12-12 22:16:21 +0000107 PyErr_SetString(PyExc_ValueError,
108 "filedescriptor out of range in select()");
109 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000110 }
111 if (v > max)
112 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000113#endif /* _MSC_VER */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000114 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000115
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000116 /* add object and its file descriptor to the list */
117 if (index >= FD_SETSIZE) {
Barry Warsawc1cb3601996-12-12 22:16:21 +0000118 PyErr_SetString(PyExc_ValueError,
119 "too many file descriptors in select()");
120 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000121 }
122 fd2obj[index].obj = o;
123 fd2obj[index].fd = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000124 fd2obj[index].sentinel = 0;
125 fd2obj[++index].sentinel = -1;
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000126 }
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000127 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000128
129 finally:
130 Py_XDECREF(o);
131 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000132}
133
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000134/* returns NULL and sets the Python exception if an error occurred */
135static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000136set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000137{
Barry Warsawc1cb3601996-12-12 22:16:21 +0000138 int i, j, count=0;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000139 PyObject *list, *o;
140 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000141
Barry Warsawc1cb3601996-12-12 22:16:21 +0000142 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000143 if (FD_ISSET(fd2obj[j].fd, set))
Barry Warsawc1cb3601996-12-12 22:16:21 +0000144 count++;
145 }
146 list = PyList_New(count);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000147 if (!list)
148 return NULL;
149
Barry Warsawc1cb3601996-12-12 22:16:21 +0000150 i = 0;
151 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000152 fd = fd2obj[j].fd;
153 if (FD_ISSET(fd, set)) {
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000154#ifndef _MSC_VER
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000155 if (fd > FD_SETSIZE) {
156 PyErr_SetString(PyExc_SystemError,
157 "filedescriptor out of range returned in select()");
Barry Warsawc1cb3601996-12-12 22:16:21 +0000158 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000159 }
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000160#endif
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000161 o = fd2obj[j].obj;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000162 fd2obj[j].obj = NULL;
163 /* transfer ownership */
164 if (PyList_SetItem(list, i, o) < 0)
165 goto finally;
166
167 i++;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000168 }
169 }
170 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000171 finally:
172 Py_DECREF(list);
173 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000174}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000175
Barry Warsawb44740f2001-08-16 16:52:59 +0000176#undef SELECT_USES_HEAP
177#if FD_SETSIZE > 1024
178#define SELECT_USES_HEAP
179#endif /* FD_SETSIZE > 1024 */
180
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000181static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000182select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000183{
Barry Warsawb44740f2001-08-16 16:52:59 +0000184#ifdef SELECT_USES_HEAP
Guido van Rossumd20781b1998-07-02 02:53:36 +0000185 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000186#else /* !SELECT_USES_HEAP */
Tim Peters4b046c22001-08-16 21:59:46 +0000187 /* XXX: All this should probably be implemented as follows:
Barry Warsawb44740f2001-08-16 16:52:59 +0000188 * - find the highest descriptor we're interested in
189 * - add one
190 * - that's the size
191 * See: Stevens, APitUE, $12.5.1
192 */
Tim Peters4b046c22001-08-16 21:59:46 +0000193 pylist rfd2obj[FD_SETSIZE + 1];
194 pylist wfd2obj[FD_SETSIZE + 1];
195 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000196#endif /* SELECT_USES_HEAP */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000197 PyObject *ifdlist, *ofdlist, *efdlist;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000198 PyObject *ret = NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000199 PyObject *tout = Py_None;
200 fd_set ifdset, ofdset, efdset;
201 double timeout;
202 struct timeval tv, *tvp;
Guido van Rossum3262e162000-06-28 21:18:13 +0000203 long seconds;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000204 int imax, omax, emax, max;
205 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000206
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000207 /* convert arguments */
Guido van Rossum43713e52000-02-29 13:59:29 +0000208 if (!PyArg_ParseTuple(args, "OOO|O:select",
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000209 &ifdlist, &ofdlist, &efdlist, &tout))
210 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000211
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000212 if (tout == Py_None)
213 tvp = (struct timeval *)0;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000214 else if (!PyArg_Parse(tout, "d", &timeout)) {
215 PyErr_SetString(PyExc_TypeError,
216 "timeout must be a float or None");
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000217 return NULL;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000218 }
Guido van Rossumc7a22701993-11-01 16:27:16 +0000219 else {
Guido van Rossum3262e162000-06-28 21:18:13 +0000220 if (timeout > (double)LONG_MAX) {
Barry Warsaw2f704552001-08-16 16:55:10 +0000221 PyErr_SetString(PyExc_OverflowError,
222 "timeout period too long");
Guido van Rossum3262e162000-06-28 21:18:13 +0000223 return NULL;
224 }
225 seconds = (long)timeout;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000226 timeout = timeout - (double)seconds;
227 tv.tv_sec = seconds;
Guido van Rossum3262e162000-06-28 21:18:13 +0000228 tv.tv_usec = (long)(timeout*1000000.0);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000229 tvp = &tv;
Guido van Rossumc7a22701993-11-01 16:27:16 +0000230 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000231
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000232 /* sanity check first three arguments */
233 if (!PyList_Check(ifdlist) ||
234 !PyList_Check(ofdlist) ||
235 !PyList_Check(efdlist))
236 {
237 PyErr_SetString(PyExc_TypeError,
238 "arguments 1-3 must be lists");
239 return NULL;
240 }
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);
Guido van Rossumd20781b1998-07-02 02:53:36 +0000251 return NULL;
252 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000253#endif /* SELECT_USES_HEAP */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000254 /* Convert lists to fd_sets, and get maximum fd number
255 * propagates the Python exception set in list2set()
256 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000257 rfd2obj[0].sentinel = -1;
258 wfd2obj[0].sentinel = -1;
259 efd2obj[0].sentinel = -1;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000260 if ((imax=list2set(ifdlist, &ifdset, rfd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000261 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000262 if ((omax=list2set(ofdlist, &ofdset, wfd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000263 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000264 if ((emax=list2set(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
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000274 if (n < 0) {
275 PyErr_SetFromErrno(SelectError);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000276 }
Barry Warsawc1cb3601996-12-12 22:16:21 +0000277 else if (n == 0) {
278 /* optimization */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000279 ifdlist = PyList_New(0);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000280 if (ifdlist) {
281 ret = Py_BuildValue("OOO", ifdlist, ifdlist, ifdlist);
282 Py_DECREF(ifdlist);
283 }
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000284 }
Barry Warsawc1cb3601996-12-12 22:16:21 +0000285 else {
286 /* any of these three calls can raise an exception. it's more
287 convenient to test for this after all three calls... but
288 is that acceptable?
289 */
290 ifdlist = set2list(&ifdset, rfd2obj);
291 ofdlist = set2list(&ofdset, wfd2obj);
292 efdlist = set2list(&efdset, efd2obj);
293 if (PyErr_Occurred())
294 ret = NULL;
295 else
296 ret = Py_BuildValue("OOO", ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000297
Barry Warsawc1cb3601996-12-12 22:16:21 +0000298 Py_DECREF(ifdlist);
299 Py_DECREF(ofdlist);
300 Py_DECREF(efdlist);
301 }
302
303 finally:
304 reap_obj(rfd2obj);
305 reap_obj(wfd2obj);
306 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000307#ifdef SELECT_USES_HEAP
Guido van Rossumd20781b1998-07-02 02:53:36 +0000308 PyMem_DEL(rfd2obj);
309 PyMem_DEL(wfd2obj);
310 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000311#endif /* SELECT_USES_HEAP */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000312 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000313}
314
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000315#ifdef HAVE_POLL
316/*
317 * poll() support
318 */
319
320typedef struct {
321 PyObject_HEAD
322 PyObject *dict;
323 int ufd_uptodate;
324 int ufd_len;
325 struct pollfd *ufds;
326} pollObject;
327
328staticforward PyTypeObject poll_Type;
329
330/* Update the malloc'ed array of pollfds to match the dictionary
331 contained within a pollObject. Return 1 on success, 0 on an error.
332*/
333
334static int
335update_ufd_array(pollObject *self)
336{
Fred Drakedff3a372001-07-19 21:29:49 +0000337 int i, pos;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000338 PyObject *key, *value;
339
340 self->ufd_len = PyDict_Size(self->dict);
341 PyMem_Resize(self->ufds, struct pollfd, self->ufd_len);
342 if (self->ufds == NULL) {
343 PyErr_NoMemory();
344 return 0;
345 }
346
347 i = pos = 0;
Fred Drakedff3a372001-07-19 21:29:49 +0000348 while (PyDict_Next(self->dict, &pos, &key, &value)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000349 self->ufds[i].fd = PyInt_AsLong(key);
Fred Drakedff3a372001-07-19 21:29:49 +0000350 self->ufds[i].events = (short)PyInt_AsLong(value);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000351 i++;
352 }
353 self->ufd_uptodate = 1;
354 return 1;
355}
356
357static char poll_register_doc[] =
358"register(fd [, eventmask] ) -> None\n\n\
359Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000360fd -- either an integer, or an object with a fileno() method returning an\n\
361 int.\n\
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000362events -- an optional bitmask describing the type of events to check for";
363
364static PyObject *
365poll_register(pollObject *self, PyObject *args)
366{
367 PyObject *o, *key, *value;
368 int fd, events = POLLIN | POLLPRI | POLLOUT;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000369 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000370
Fred Drake7b87f852001-05-21 03:29:05 +0000371 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000372 return NULL;
373 }
374
375 fd = PyObject_AsFileDescriptor(o);
376 if (fd == -1) return NULL;
377
378 /* Add entry to the internal dictionary: the key is the
379 file descriptor, and the value is the event mask. */
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000380 key = PyInt_FromLong(fd);
381 if (key == NULL)
382 return NULL;
383 value = PyInt_FromLong(events);
384 if (value == NULL) {
385 Py_DECREF(key);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000386 return NULL;
387 }
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000388 err = PyDict_SetItem(self->dict, key, value);
389 Py_DECREF(key);
390 Py_DECREF(value);
391 if (err < 0)
392 return NULL;
393
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000394 self->ufd_uptodate = 0;
395
396 Py_INCREF(Py_None);
397 return Py_None;
398}
399
400static char poll_unregister_doc[] =
401"unregister(fd) -> None\n\n\
402Remove a file descriptor being tracked by the polling object.";
403
404static PyObject *
405poll_unregister(pollObject *self, PyObject *args)
406{
407 PyObject *o, *key;
408 int fd;
409
Fred Drake7b87f852001-05-21 03:29:05 +0000410 if (!PyArg_ParseTuple(args, "O:unregister", &o)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000411 return NULL;
412 }
413
414 fd = PyObject_AsFileDescriptor( o );
415 if (fd == -1)
416 return NULL;
417
418 /* Check whether the fd is already in the array */
419 key = PyInt_FromLong(fd);
420 if (key == NULL)
421 return NULL;
422
423 if (PyDict_DelItem(self->dict, key) == -1) {
424 Py_DECREF(key);
425 /* This will simply raise the KeyError set by PyDict_DelItem
426 if the file descriptor isn't registered. */
427 return NULL;
428 }
429
430 Py_DECREF(key);
431 self->ufd_uptodate = 0;
432
433 Py_INCREF(Py_None);
434 return Py_None;
435}
436
437static char poll_poll_doc[] =
438"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
439Polls the set of registered file descriptors, returning a list containing \n\
440any descriptors that have events or errors to report.";
441
442static PyObject *
443poll_poll(pollObject *self, PyObject *args)
444{
445 PyObject *result_list = NULL, *tout = NULL;
446 int timeout = 0, poll_result, i, j;
447 PyObject *value = NULL, *num = NULL;
448
Fred Drake7b87f852001-05-21 03:29:05 +0000449 if (!PyArg_ParseTuple(args, "|O:poll", &tout)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000450 return NULL;
451 }
452
453 /* Check values for timeout */
454 if (tout == NULL || tout == Py_None)
455 timeout = -1;
456 else if (!PyArg_Parse(tout, "i", &timeout)) {
457 PyErr_SetString(PyExc_TypeError,
458 "timeout must be an integer or None");
459 return NULL;
460 }
461
462 /* Ensure the ufd array is up to date */
463 if (!self->ufd_uptodate)
464 if (update_ufd_array(self) == 0)
465 return NULL;
466
467 /* call poll() */
468 Py_BEGIN_ALLOW_THREADS;
469 poll_result = poll(self->ufds, self->ufd_len, timeout);
470 Py_END_ALLOW_THREADS;
471
472 if (poll_result < 0) {
473 PyErr_SetFromErrno(SelectError);
474 return NULL;
475 }
476
477 /* build the result list */
478
479 result_list = PyList_New(poll_result);
480 if (!result_list)
481 return NULL;
482 else {
483 for (i = 0, j = 0; j < poll_result; j++) {
484 /* skip to the next fired descriptor */
485 while (!self->ufds[i].revents) {
486 i++;
487 }
488 /* if we hit a NULL return, set value to NULL
489 and break out of loop; code at end will
490 clean up result_list */
491 value = PyTuple_New(2);
492 if (value == NULL)
493 goto error;
494 num = PyInt_FromLong(self->ufds[i].fd);
495 if (num == NULL) {
496 Py_DECREF(value);
497 goto error;
498 }
499 PyTuple_SET_ITEM(value, 0, num);
500
501 num = PyInt_FromLong(self->ufds[i].revents);
502 if (num == NULL) {
503 Py_DECREF(value);
504 goto error;
505 }
506 PyTuple_SET_ITEM(value, 1, num);
507 if ((PyList_SetItem(result_list, j, value)) == -1) {
508 Py_DECREF(value);
509 goto error;
510 }
511 i++;
512 }
513 }
514 return result_list;
515
516 error:
517 Py_DECREF(result_list);
518 return NULL;
519}
520
521static PyMethodDef poll_methods[] = {
522 {"register", (PyCFunction)poll_register,
523 METH_VARARGS, poll_register_doc},
524 {"unregister", (PyCFunction)poll_unregister,
525 METH_VARARGS, poll_unregister_doc},
526 {"poll", (PyCFunction)poll_poll,
527 METH_VARARGS, poll_poll_doc},
528 {NULL, NULL} /* sentinel */
529};
530
531static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000532newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000533{
534 pollObject *self;
535 self = PyObject_New(pollObject, &poll_Type);
536 if (self == NULL)
537 return NULL;
538 /* ufd_uptodate is a Boolean, denoting whether the
539 array pointed to by ufds matches the contents of the dictionary. */
540 self->ufd_uptodate = 0;
541 self->ufds = NULL;
542 self->dict = PyDict_New();
543 if (self->dict == NULL) {
544 Py_DECREF(self);
545 return NULL;
546 }
547 return self;
548}
549
550static void
551poll_dealloc(pollObject *self)
552{
553 if (self->ufds != NULL)
554 PyMem_DEL(self->ufds);
555 Py_XDECREF(self->dict);
556 PyObject_Del(self);
557}
558
559static PyObject *
560poll_getattr(pollObject *self, char *name)
561{
562 return Py_FindMethod(poll_methods, (PyObject *)self, name);
563}
564
565statichere PyTypeObject poll_Type = {
566 /* The ob_type field must be initialized in the module init function
567 * to be portable to Windows without using C++. */
568 PyObject_HEAD_INIT(NULL)
569 0, /*ob_size*/
Guido van Rossum14648392001-12-08 18:02:58 +0000570 "select.poll", /*tp_name*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000571 sizeof(pollObject), /*tp_basicsize*/
572 0, /*tp_itemsize*/
573 /* methods */
574 (destructor)poll_dealloc, /*tp_dealloc*/
575 0, /*tp_print*/
576 (getattrfunc)poll_getattr, /*tp_getattr*/
577 0, /*tp_setattr*/
578 0, /*tp_compare*/
579 0, /*tp_repr*/
580 0, /*tp_as_number*/
581 0, /*tp_as_sequence*/
582 0, /*tp_as_mapping*/
583 0, /*tp_hash*/
584};
585
586static char poll_doc[] =
587"Returns a polling object, which supports registering and\n\
588unregistering file descriptors, and then polling them for I/O events.";
589
590static PyObject *
591select_poll(PyObject *self, PyObject *args)
592{
593 pollObject *rv;
594
595 if (!PyArg_ParseTuple(args, ":poll"))
596 return NULL;
597 rv = newPollObject();
598 if ( rv == NULL )
599 return NULL;
600 return (PyObject *)rv;
601}
602#endif /* HAVE_POLL */
603
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000604static char select_doc[] =
605"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
606\n\
607Wait until one or more file descriptors are ready for some kind of I/O.\n\
608The first three arguments are lists of file descriptors to be waited for:\n\
609rlist -- wait until ready for reading\n\
610wlist -- wait until ready for writing\n\
611xlist -- wait for an ``exceptional condition''\n\
612If only one kind of condition is required, pass [] for the other lists.\n\
613A file descriptor is either a socket or file object, or a small integer\n\
614gotten from a fileno() method call on one of those.\n\
615\n\
616The optional 4th argument specifies a timeout in seconds; it may be\n\
617a floating point number to specify fractions of seconds. If it is absent\n\
618or None, the call will never time out.\n\
619\n\
620The return value is a tuple of three lists corresponding to the first three\n\
621arguments; each contains the subset of the corresponding file descriptors\n\
622that are ready.\n\
623\n\
624*** IMPORTANT NOTICE ***\n\
625On Windows, only sockets are supported; on Unix, all file descriptors.";
626
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000627static PyMethodDef select_methods[] = {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000628 {"select", select_select, METH_VARARGS, select_doc},
629#ifdef HAVE_POLL
630 {"poll", select_poll, METH_VARARGS, poll_doc},
631#endif /* HAVE_POLL */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000632 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +0000633};
634
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000635static char module_doc[] =
636"This module supports asynchronous I/O on multiple file descriptors.\n\
637\n\
638*** IMPORTANT NOTICE ***\n\
639On Windows, only sockets are supported; on Unix, all file descriptors.";
Guido van Rossumed233a51992-06-23 09:07:03 +0000640
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000641/*
642 * Convenience routine to export an integer value.
643 * For simplicity, errors (which are unlikely anyway) are ignored.
644 */
645
646static void
647insint(PyObject *d, char *name, int value)
648{
649 PyObject *v = PyInt_FromLong((long) value);
650 if (v == NULL) {
651 /* Don't bother reporting this error */
652 PyErr_Clear();
653 }
654 else {
655 PyDict_SetItemString(d, name, v);
656 Py_DECREF(v);
657 }
658}
659
Guido van Rossum3886bb61998-12-04 18:50:17 +0000660DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000661initselect(void)
Guido van Rossumed233a51992-06-23 09:07:03 +0000662{
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000663 PyObject *m, *d;
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000664 m = Py_InitModule3("select", select_methods, module_doc);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000665 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000666 SelectError = PyErr_NewException("select.error", NULL, NULL);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000667 PyDict_SetItemString(d, "error", SelectError);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000668#ifdef HAVE_POLL
669 poll_Type.ob_type = &PyType_Type;
670 insint(d, "POLLIN", POLLIN);
671 insint(d, "POLLPRI", POLLPRI);
672 insint(d, "POLLOUT", POLLOUT);
673 insint(d, "POLLERR", POLLERR);
674 insint(d, "POLLHUP", POLLHUP);
675 insint(d, "POLLNVAL", POLLNVAL);
676
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000677#ifdef POLLRDNORM
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000678 insint(d, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000679#endif
680#ifdef POLLRDBAND
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000681 insint(d, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000682#endif
683#ifdef POLLWRNORM
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000684 insint(d, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000685#endif
686#ifdef POLLWRBAND
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000687 insint(d, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000688#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +0000689#ifdef POLLMSG
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000690 insint(d, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +0000691#endif
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000692#endif /* HAVE_POLL */
Guido van Rossumed233a51992-06-23 09:07:03 +0000693}