blob: e480fb47851728e10521cfc553a2ce381d91b5fd [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;
369
Fred Drake7b87f852001-05-21 03:29:05 +0000370 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000371 return NULL;
372 }
373
374 fd = PyObject_AsFileDescriptor(o);
375 if (fd == -1) return NULL;
376
377 /* Add entry to the internal dictionary: the key is the
378 file descriptor, and the value is the event mask. */
379 if ( (NULL == (key = PyInt_FromLong(fd))) ||
380 (NULL == (value = PyInt_FromLong(events))) ||
381 (PyDict_SetItem(self->dict, key, value)) == -1) {
382 return NULL;
383 }
384 self->ufd_uptodate = 0;
385
386 Py_INCREF(Py_None);
387 return Py_None;
388}
389
390static char poll_unregister_doc[] =
391"unregister(fd) -> None\n\n\
392Remove a file descriptor being tracked by the polling object.";
393
394static PyObject *
395poll_unregister(pollObject *self, PyObject *args)
396{
397 PyObject *o, *key;
398 int fd;
399
Fred Drake7b87f852001-05-21 03:29:05 +0000400 if (!PyArg_ParseTuple(args, "O:unregister", &o)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000401 return NULL;
402 }
403
404 fd = PyObject_AsFileDescriptor( o );
405 if (fd == -1)
406 return NULL;
407
408 /* Check whether the fd is already in the array */
409 key = PyInt_FromLong(fd);
410 if (key == NULL)
411 return NULL;
412
413 if (PyDict_DelItem(self->dict, key) == -1) {
414 Py_DECREF(key);
415 /* This will simply raise the KeyError set by PyDict_DelItem
416 if the file descriptor isn't registered. */
417 return NULL;
418 }
419
420 Py_DECREF(key);
421 self->ufd_uptodate = 0;
422
423 Py_INCREF(Py_None);
424 return Py_None;
425}
426
427static char poll_poll_doc[] =
428"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
429Polls the set of registered file descriptors, returning a list containing \n\
430any descriptors that have events or errors to report.";
431
432static PyObject *
433poll_poll(pollObject *self, PyObject *args)
434{
435 PyObject *result_list = NULL, *tout = NULL;
436 int timeout = 0, poll_result, i, j;
437 PyObject *value = NULL, *num = NULL;
438
Fred Drake7b87f852001-05-21 03:29:05 +0000439 if (!PyArg_ParseTuple(args, "|O:poll", &tout)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000440 return NULL;
441 }
442
443 /* Check values for timeout */
444 if (tout == NULL || tout == Py_None)
445 timeout = -1;
446 else if (!PyArg_Parse(tout, "i", &timeout)) {
447 PyErr_SetString(PyExc_TypeError,
448 "timeout must be an integer or None");
449 return NULL;
450 }
451
452 /* Ensure the ufd array is up to date */
453 if (!self->ufd_uptodate)
454 if (update_ufd_array(self) == 0)
455 return NULL;
456
457 /* call poll() */
458 Py_BEGIN_ALLOW_THREADS;
459 poll_result = poll(self->ufds, self->ufd_len, timeout);
460 Py_END_ALLOW_THREADS;
461
462 if (poll_result < 0) {
463 PyErr_SetFromErrno(SelectError);
464 return NULL;
465 }
466
467 /* build the result list */
468
469 result_list = PyList_New(poll_result);
470 if (!result_list)
471 return NULL;
472 else {
473 for (i = 0, j = 0; j < poll_result; j++) {
474 /* skip to the next fired descriptor */
475 while (!self->ufds[i].revents) {
476 i++;
477 }
478 /* if we hit a NULL return, set value to NULL
479 and break out of loop; code at end will
480 clean up result_list */
481 value = PyTuple_New(2);
482 if (value == NULL)
483 goto error;
484 num = PyInt_FromLong(self->ufds[i].fd);
485 if (num == NULL) {
486 Py_DECREF(value);
487 goto error;
488 }
489 PyTuple_SET_ITEM(value, 0, num);
490
491 num = PyInt_FromLong(self->ufds[i].revents);
492 if (num == NULL) {
493 Py_DECREF(value);
494 goto error;
495 }
496 PyTuple_SET_ITEM(value, 1, num);
497 if ((PyList_SetItem(result_list, j, value)) == -1) {
498 Py_DECREF(value);
499 goto error;
500 }
501 i++;
502 }
503 }
504 return result_list;
505
506 error:
507 Py_DECREF(result_list);
508 return NULL;
509}
510
511static PyMethodDef poll_methods[] = {
512 {"register", (PyCFunction)poll_register,
513 METH_VARARGS, poll_register_doc},
514 {"unregister", (PyCFunction)poll_unregister,
515 METH_VARARGS, poll_unregister_doc},
516 {"poll", (PyCFunction)poll_poll,
517 METH_VARARGS, poll_poll_doc},
518 {NULL, NULL} /* sentinel */
519};
520
521static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000522newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000523{
524 pollObject *self;
525 self = PyObject_New(pollObject, &poll_Type);
526 if (self == NULL)
527 return NULL;
528 /* ufd_uptodate is a Boolean, denoting whether the
529 array pointed to by ufds matches the contents of the dictionary. */
530 self->ufd_uptodate = 0;
531 self->ufds = NULL;
532 self->dict = PyDict_New();
533 if (self->dict == NULL) {
534 Py_DECREF(self);
535 return NULL;
536 }
537 return self;
538}
539
540static void
541poll_dealloc(pollObject *self)
542{
543 if (self->ufds != NULL)
544 PyMem_DEL(self->ufds);
545 Py_XDECREF(self->dict);
546 PyObject_Del(self);
547}
548
549static PyObject *
550poll_getattr(pollObject *self, char *name)
551{
552 return Py_FindMethod(poll_methods, (PyObject *)self, name);
553}
554
555statichere PyTypeObject poll_Type = {
556 /* The ob_type field must be initialized in the module init function
557 * to be portable to Windows without using C++. */
558 PyObject_HEAD_INIT(NULL)
559 0, /*ob_size*/
560 "poll", /*tp_name*/
561 sizeof(pollObject), /*tp_basicsize*/
562 0, /*tp_itemsize*/
563 /* methods */
564 (destructor)poll_dealloc, /*tp_dealloc*/
565 0, /*tp_print*/
566 (getattrfunc)poll_getattr, /*tp_getattr*/
567 0, /*tp_setattr*/
568 0, /*tp_compare*/
569 0, /*tp_repr*/
570 0, /*tp_as_number*/
571 0, /*tp_as_sequence*/
572 0, /*tp_as_mapping*/
573 0, /*tp_hash*/
574};
575
576static char poll_doc[] =
577"Returns a polling object, which supports registering and\n\
578unregistering file descriptors, and then polling them for I/O events.";
579
580static PyObject *
581select_poll(PyObject *self, PyObject *args)
582{
583 pollObject *rv;
584
585 if (!PyArg_ParseTuple(args, ":poll"))
586 return NULL;
587 rv = newPollObject();
588 if ( rv == NULL )
589 return NULL;
590 return (PyObject *)rv;
591}
592#endif /* HAVE_POLL */
593
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000594static char select_doc[] =
595"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
596\n\
597Wait until one or more file descriptors are ready for some kind of I/O.\n\
598The first three arguments are lists of file descriptors to be waited for:\n\
599rlist -- wait until ready for reading\n\
600wlist -- wait until ready for writing\n\
601xlist -- wait for an ``exceptional condition''\n\
602If only one kind of condition is required, pass [] for the other lists.\n\
603A file descriptor is either a socket or file object, or a small integer\n\
604gotten from a fileno() method call on one of those.\n\
605\n\
606The optional 4th argument specifies a timeout in seconds; it may be\n\
607a floating point number to specify fractions of seconds. If it is absent\n\
608or None, the call will never time out.\n\
609\n\
610The return value is a tuple of three lists corresponding to the first three\n\
611arguments; each contains the subset of the corresponding file descriptors\n\
612that are ready.\n\
613\n\
614*** IMPORTANT NOTICE ***\n\
615On Windows, only sockets are supported; on Unix, all file descriptors.";
616
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000617static PyMethodDef select_methods[] = {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000618 {"select", select_select, METH_VARARGS, select_doc},
619#ifdef HAVE_POLL
620 {"poll", select_poll, METH_VARARGS, poll_doc},
621#endif /* HAVE_POLL */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000622 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +0000623};
624
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000625static char module_doc[] =
626"This module supports asynchronous I/O on multiple file descriptors.\n\
627\n\
628*** IMPORTANT NOTICE ***\n\
629On Windows, only sockets are supported; on Unix, all file descriptors.";
Guido van Rossumed233a51992-06-23 09:07:03 +0000630
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000631/*
632 * Convenience routine to export an integer value.
633 * For simplicity, errors (which are unlikely anyway) are ignored.
634 */
635
636static void
637insint(PyObject *d, char *name, int value)
638{
639 PyObject *v = PyInt_FromLong((long) value);
640 if (v == NULL) {
641 /* Don't bother reporting this error */
642 PyErr_Clear();
643 }
644 else {
645 PyDict_SetItemString(d, name, v);
646 Py_DECREF(v);
647 }
648}
649
Guido van Rossum3886bb61998-12-04 18:50:17 +0000650DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000651initselect(void)
Guido van Rossumed233a51992-06-23 09:07:03 +0000652{
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000653 PyObject *m, *d;
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000654 m = Py_InitModule3("select", select_methods, module_doc);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000655 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000656 SelectError = PyErr_NewException("select.error", NULL, NULL);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000657 PyDict_SetItemString(d, "error", SelectError);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000658#ifdef HAVE_POLL
659 poll_Type.ob_type = &PyType_Type;
660 insint(d, "POLLIN", POLLIN);
661 insint(d, "POLLPRI", POLLPRI);
662 insint(d, "POLLOUT", POLLOUT);
663 insint(d, "POLLERR", POLLERR);
664 insint(d, "POLLHUP", POLLHUP);
665 insint(d, "POLLNVAL", POLLNVAL);
666
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000667#ifdef POLLRDNORM
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000668 insint(d, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000669#endif
670#ifdef POLLRDBAND
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000671 insint(d, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000672#endif
673#ifdef POLLWRNORM
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000674 insint(d, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000675#endif
676#ifdef POLLWRBAND
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000677 insint(d, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000678#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +0000679#ifdef POLLMSG
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000680 insint(d, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +0000681#endif
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000682#endif /* HAVE_POLL */
Guido van Rossumed233a51992-06-23 09:07:03 +0000683}