blob: 0a29f2efd5ce5c80e1055d80aabd230d078971c1 [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
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000042#include <winsock.h>
43#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
Tim Peters4b046c22001-08-16 21:59:46 +000078list2set(PyObject *list, 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;
83 int len = PyList_Size(list);
84 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000085
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000086 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000087 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000088
89 for (i = 0; i < len; i++) {
Barry Warsawc1cb3601996-12-12 22:16:21 +000090 SOCKET v;
91
92 /* any intervening fileno() calls could decr this refcnt */
Barry Warsaw24c4b3d1996-12-13 23:22:42 +000093 if (!(o = PyList_GetItem(list, i)))
Barry Warsaw529fcfe1996-12-16 18:15:34 +000094 return -1;
Barry Warsaw24c4b3d1996-12-13 23:22:42 +000095
Barry Warsawc1cb3601996-12-12 22:16:21 +000096 Py_INCREF(o);
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +000097 v = PyObject_AsFileDescriptor( o );
98 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +000099
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000100#if defined(_MSC_VER)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000101 max = 0; /* not used for Win32 */
102#else /* !_MSC_VER */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000103 if (v < 0 || v >= FD_SETSIZE) {
Barry Warsawc1cb3601996-12-12 22:16:21 +0000104 PyErr_SetString(PyExc_ValueError,
105 "filedescriptor out of range in select()");
106 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000107 }
108 if (v > max)
109 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000110#endif /* _MSC_VER */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000111 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000112
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000113 /* add object and its file descriptor to the list */
114 if (index >= FD_SETSIZE) {
Barry Warsawc1cb3601996-12-12 22:16:21 +0000115 PyErr_SetString(PyExc_ValueError,
116 "too many file descriptors in select()");
117 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000118 }
119 fd2obj[index].obj = o;
120 fd2obj[index].fd = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000121 fd2obj[index].sentinel = 0;
122 fd2obj[++index].sentinel = -1;
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000123 }
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000124 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000125
126 finally:
127 Py_XDECREF(o);
128 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000129}
130
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000131/* returns NULL and sets the Python exception if an error occurred */
132static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000133set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000134{
Barry Warsawc1cb3601996-12-12 22:16:21 +0000135 int i, j, count=0;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000136 PyObject *list, *o;
137 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000138
Barry Warsawc1cb3601996-12-12 22:16:21 +0000139 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000140 if (FD_ISSET(fd2obj[j].fd, set))
Barry Warsawc1cb3601996-12-12 22:16:21 +0000141 count++;
142 }
143 list = PyList_New(count);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000144 if (!list)
145 return NULL;
146
Barry Warsawc1cb3601996-12-12 22:16:21 +0000147 i = 0;
148 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000149 fd = fd2obj[j].fd;
150 if (FD_ISSET(fd, set)) {
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000151#ifndef _MSC_VER
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000152 if (fd > FD_SETSIZE) {
153 PyErr_SetString(PyExc_SystemError,
154 "filedescriptor out of range returned in select()");
Barry Warsawc1cb3601996-12-12 22:16:21 +0000155 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000156 }
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000157#endif
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000158 o = fd2obj[j].obj;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000159 fd2obj[j].obj = NULL;
160 /* transfer ownership */
161 if (PyList_SetItem(list, i, o) < 0)
162 goto finally;
163
164 i++;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000165 }
166 }
167 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000168 finally:
169 Py_DECREF(list);
170 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000171}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000172
Barry Warsawb44740f2001-08-16 16:52:59 +0000173#undef SELECT_USES_HEAP
174#if FD_SETSIZE > 1024
175#define SELECT_USES_HEAP
176#endif /* FD_SETSIZE > 1024 */
177
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000178static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000179select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000180{
Barry Warsawb44740f2001-08-16 16:52:59 +0000181#ifdef SELECT_USES_HEAP
Guido van Rossumd20781b1998-07-02 02:53:36 +0000182 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000183#else /* !SELECT_USES_HEAP */
Tim Peters4b046c22001-08-16 21:59:46 +0000184 /* XXX: All this should probably be implemented as follows:
Barry Warsawb44740f2001-08-16 16:52:59 +0000185 * - find the highest descriptor we're interested in
186 * - add one
187 * - that's the size
188 * See: Stevens, APitUE, $12.5.1
189 */
Tim Peters4b046c22001-08-16 21:59:46 +0000190 pylist rfd2obj[FD_SETSIZE + 1];
191 pylist wfd2obj[FD_SETSIZE + 1];
192 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000193#endif /* SELECT_USES_HEAP */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000194 PyObject *ifdlist, *ofdlist, *efdlist;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000195 PyObject *ret = NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000196 PyObject *tout = Py_None;
197 fd_set ifdset, ofdset, efdset;
198 double timeout;
199 struct timeval tv, *tvp;
Guido van Rossum3262e162000-06-28 21:18:13 +0000200 long seconds;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000201 int imax, omax, emax, max;
202 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000203
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000204 /* convert arguments */
Guido van Rossum43713e52000-02-29 13:59:29 +0000205 if (!PyArg_ParseTuple(args, "OOO|O:select",
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000206 &ifdlist, &ofdlist, &efdlist, &tout))
207 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000208
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000209 if (tout == Py_None)
210 tvp = (struct timeval *)0;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000211 else if (!PyArg_Parse(tout, "d", &timeout)) {
212 PyErr_SetString(PyExc_TypeError,
213 "timeout must be a float or None");
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000214 return NULL;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000215 }
Guido van Rossumc7a22701993-11-01 16:27:16 +0000216 else {
Guido van Rossum3262e162000-06-28 21:18:13 +0000217 if (timeout > (double)LONG_MAX) {
Barry Warsaw2f704552001-08-16 16:55:10 +0000218 PyErr_SetString(PyExc_OverflowError,
219 "timeout period too long");
Guido van Rossum3262e162000-06-28 21:18:13 +0000220 return NULL;
221 }
222 seconds = (long)timeout;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000223 timeout = timeout - (double)seconds;
224 tv.tv_sec = seconds;
Guido van Rossum3262e162000-06-28 21:18:13 +0000225 tv.tv_usec = (long)(timeout*1000000.0);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000226 tvp = &tv;
Guido van Rossumc7a22701993-11-01 16:27:16 +0000227 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000228
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000229 /* sanity check first three arguments */
230 if (!PyList_Check(ifdlist) ||
231 !PyList_Check(ofdlist) ||
232 !PyList_Check(efdlist))
233 {
234 PyErr_SetString(PyExc_TypeError,
235 "arguments 1-3 must be lists");
236 return NULL;
237 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000238
Barry Warsawb44740f2001-08-16 16:52:59 +0000239#ifdef SELECT_USES_HEAP
Guido van Rossumd20781b1998-07-02 02:53:36 +0000240 /* Allocate memory for the lists */
Tim Peters4b046c22001-08-16 21:59:46 +0000241 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
242 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
243 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
Guido van Rossumd20781b1998-07-02 02:53:36 +0000244 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
Guido van Rossumb18618d2000-05-03 23:44:39 +0000245 if (rfd2obj) PyMem_DEL(rfd2obj);
246 if (wfd2obj) PyMem_DEL(wfd2obj);
247 if (efd2obj) PyMem_DEL(efd2obj);
Guido van Rossumd20781b1998-07-02 02:53:36 +0000248 return NULL;
249 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000250#endif /* SELECT_USES_HEAP */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000251 /* Convert lists to fd_sets, and get maximum fd number
252 * propagates the Python exception set in list2set()
253 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000254 rfd2obj[0].sentinel = -1;
255 wfd2obj[0].sentinel = -1;
256 efd2obj[0].sentinel = -1;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000257 if ((imax=list2set(ifdlist, &ifdset, rfd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000258 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000259 if ((omax=list2set(ofdlist, &ofdset, wfd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000260 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000261 if ((emax=list2set(efdlist, &efdset, efd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000262 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000263 max = imax;
264 if (omax > max) max = omax;
265 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000266
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000267 Py_BEGIN_ALLOW_THREADS
268 n = select(max, &ifdset, &ofdset, &efdset, tvp);
269 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000270
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000271 if (n < 0) {
272 PyErr_SetFromErrno(SelectError);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000273 }
Barry Warsawc1cb3601996-12-12 22:16:21 +0000274 else if (n == 0) {
275 /* optimization */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000276 ifdlist = PyList_New(0);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000277 if (ifdlist) {
278 ret = Py_BuildValue("OOO", ifdlist, ifdlist, ifdlist);
279 Py_DECREF(ifdlist);
280 }
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000281 }
Barry Warsawc1cb3601996-12-12 22:16:21 +0000282 else {
283 /* any of these three calls can raise an exception. it's more
284 convenient to test for this after all three calls... but
285 is that acceptable?
286 */
287 ifdlist = set2list(&ifdset, rfd2obj);
288 ofdlist = set2list(&ofdset, wfd2obj);
289 efdlist = set2list(&efdset, efd2obj);
290 if (PyErr_Occurred())
291 ret = NULL;
292 else
293 ret = Py_BuildValue("OOO", ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000294
Barry Warsawc1cb3601996-12-12 22:16:21 +0000295 Py_DECREF(ifdlist);
296 Py_DECREF(ofdlist);
297 Py_DECREF(efdlist);
298 }
299
300 finally:
301 reap_obj(rfd2obj);
302 reap_obj(wfd2obj);
303 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000304#ifdef SELECT_USES_HEAP
Guido van Rossumd20781b1998-07-02 02:53:36 +0000305 PyMem_DEL(rfd2obj);
306 PyMem_DEL(wfd2obj);
307 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000308#endif /* SELECT_USES_HEAP */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000309 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000310}
311
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000312#ifdef HAVE_POLL
313/*
314 * poll() support
315 */
316
317typedef struct {
318 PyObject_HEAD
319 PyObject *dict;
320 int ufd_uptodate;
321 int ufd_len;
322 struct pollfd *ufds;
323} pollObject;
324
325staticforward PyTypeObject poll_Type;
326
327/* Update the malloc'ed array of pollfds to match the dictionary
328 contained within a pollObject. Return 1 on success, 0 on an error.
329*/
330
331static int
332update_ufd_array(pollObject *self)
333{
Fred Drakedff3a372001-07-19 21:29:49 +0000334 int i, pos;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000335 PyObject *key, *value;
336
337 self->ufd_len = PyDict_Size(self->dict);
338 PyMem_Resize(self->ufds, struct pollfd, self->ufd_len);
339 if (self->ufds == NULL) {
340 PyErr_NoMemory();
341 return 0;
342 }
343
344 i = pos = 0;
Fred Drakedff3a372001-07-19 21:29:49 +0000345 while (PyDict_Next(self->dict, &pos, &key, &value)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000346 self->ufds[i].fd = PyInt_AsLong(key);
Fred Drakedff3a372001-07-19 21:29:49 +0000347 self->ufds[i].events = (short)PyInt_AsLong(value);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000348 i++;
349 }
350 self->ufd_uptodate = 1;
351 return 1;
352}
353
354static char poll_register_doc[] =
355"register(fd [, eventmask] ) -> None\n\n\
356Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000357fd -- either an integer, or an object with a fileno() method returning an\n\
358 int.\n\
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000359events -- an optional bitmask describing the type of events to check for";
360
361static PyObject *
362poll_register(pollObject *self, PyObject *args)
363{
364 PyObject *o, *key, *value;
365 int fd, events = POLLIN | POLLPRI | POLLOUT;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000366 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000367
Fred Drake7b87f852001-05-21 03:29:05 +0000368 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000369 return NULL;
370 }
371
372 fd = PyObject_AsFileDescriptor(o);
373 if (fd == -1) return NULL;
374
375 /* Add entry to the internal dictionary: the key is the
376 file descriptor, and the value is the event mask. */
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000377 key = PyInt_FromLong(fd);
378 if (key == NULL)
379 return NULL;
380 value = PyInt_FromLong(events);
381 if (value == NULL) {
382 Py_DECREF(key);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000383 return NULL;
384 }
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000385 err = PyDict_SetItem(self->dict, key, value);
386 Py_DECREF(key);
387 Py_DECREF(value);
388 if (err < 0)
389 return NULL;
390
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000391 self->ufd_uptodate = 0;
392
393 Py_INCREF(Py_None);
394 return Py_None;
395}
396
397static char poll_unregister_doc[] =
398"unregister(fd) -> None\n\n\
399Remove a file descriptor being tracked by the polling object.";
400
401static PyObject *
402poll_unregister(pollObject *self, PyObject *args)
403{
404 PyObject *o, *key;
405 int fd;
406
Fred Drake7b87f852001-05-21 03:29:05 +0000407 if (!PyArg_ParseTuple(args, "O:unregister", &o)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000408 return NULL;
409 }
410
411 fd = PyObject_AsFileDescriptor( o );
412 if (fd == -1)
413 return NULL;
414
415 /* Check whether the fd is already in the array */
416 key = PyInt_FromLong(fd);
417 if (key == NULL)
418 return NULL;
419
420 if (PyDict_DelItem(self->dict, key) == -1) {
421 Py_DECREF(key);
422 /* This will simply raise the KeyError set by PyDict_DelItem
423 if the file descriptor isn't registered. */
424 return NULL;
425 }
426
427 Py_DECREF(key);
428 self->ufd_uptodate = 0;
429
430 Py_INCREF(Py_None);
431 return Py_None;
432}
433
434static char poll_poll_doc[] =
435"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
436Polls the set of registered file descriptors, returning a list containing \n\
437any descriptors that have events or errors to report.";
438
439static PyObject *
440poll_poll(pollObject *self, PyObject *args)
441{
442 PyObject *result_list = NULL, *tout = NULL;
443 int timeout = 0, poll_result, i, j;
444 PyObject *value = NULL, *num = NULL;
445
Fred Drake7b87f852001-05-21 03:29:05 +0000446 if (!PyArg_ParseTuple(args, "|O:poll", &tout)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000447 return NULL;
448 }
449
450 /* Check values for timeout */
451 if (tout == NULL || tout == Py_None)
452 timeout = -1;
453 else if (!PyArg_Parse(tout, "i", &timeout)) {
454 PyErr_SetString(PyExc_TypeError,
455 "timeout must be an integer or None");
456 return NULL;
457 }
458
459 /* Ensure the ufd array is up to date */
460 if (!self->ufd_uptodate)
461 if (update_ufd_array(self) == 0)
462 return NULL;
463
464 /* call poll() */
465 Py_BEGIN_ALLOW_THREADS;
466 poll_result = poll(self->ufds, self->ufd_len, timeout);
467 Py_END_ALLOW_THREADS;
468
469 if (poll_result < 0) {
470 PyErr_SetFromErrno(SelectError);
471 return NULL;
472 }
473
474 /* build the result list */
475
476 result_list = PyList_New(poll_result);
477 if (!result_list)
478 return NULL;
479 else {
480 for (i = 0, j = 0; j < poll_result; j++) {
481 /* skip to the next fired descriptor */
482 while (!self->ufds[i].revents) {
483 i++;
484 }
485 /* if we hit a NULL return, set value to NULL
486 and break out of loop; code at end will
487 clean up result_list */
488 value = PyTuple_New(2);
489 if (value == NULL)
490 goto error;
491 num = PyInt_FromLong(self->ufds[i].fd);
492 if (num == NULL) {
493 Py_DECREF(value);
494 goto error;
495 }
496 PyTuple_SET_ITEM(value, 0, num);
497
498 num = PyInt_FromLong(self->ufds[i].revents);
499 if (num == NULL) {
500 Py_DECREF(value);
501 goto error;
502 }
503 PyTuple_SET_ITEM(value, 1, num);
504 if ((PyList_SetItem(result_list, j, value)) == -1) {
505 Py_DECREF(value);
506 goto error;
507 }
508 i++;
509 }
510 }
511 return result_list;
512
513 error:
514 Py_DECREF(result_list);
515 return NULL;
516}
517
518static PyMethodDef poll_methods[] = {
519 {"register", (PyCFunction)poll_register,
520 METH_VARARGS, poll_register_doc},
521 {"unregister", (PyCFunction)poll_unregister,
522 METH_VARARGS, poll_unregister_doc},
523 {"poll", (PyCFunction)poll_poll,
524 METH_VARARGS, poll_poll_doc},
525 {NULL, NULL} /* sentinel */
526};
527
528static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000529newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000530{
531 pollObject *self;
532 self = PyObject_New(pollObject, &poll_Type);
533 if (self == NULL)
534 return NULL;
535 /* ufd_uptodate is a Boolean, denoting whether the
536 array pointed to by ufds matches the contents of the dictionary. */
537 self->ufd_uptodate = 0;
538 self->ufds = NULL;
539 self->dict = PyDict_New();
540 if (self->dict == NULL) {
541 Py_DECREF(self);
542 return NULL;
543 }
544 return self;
545}
546
547static void
548poll_dealloc(pollObject *self)
549{
550 if (self->ufds != NULL)
551 PyMem_DEL(self->ufds);
552 Py_XDECREF(self->dict);
553 PyObject_Del(self);
554}
555
556static PyObject *
557poll_getattr(pollObject *self, char *name)
558{
559 return Py_FindMethod(poll_methods, (PyObject *)self, name);
560}
561
562statichere PyTypeObject poll_Type = {
563 /* The ob_type field must be initialized in the module init function
564 * to be portable to Windows without using C++. */
565 PyObject_HEAD_INIT(NULL)
566 0, /*ob_size*/
Guido van Rossum14648392001-12-08 18:02:58 +0000567 "select.poll", /*tp_name*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000568 sizeof(pollObject), /*tp_basicsize*/
569 0, /*tp_itemsize*/
570 /* methods */
571 (destructor)poll_dealloc, /*tp_dealloc*/
572 0, /*tp_print*/
573 (getattrfunc)poll_getattr, /*tp_getattr*/
574 0, /*tp_setattr*/
575 0, /*tp_compare*/
576 0, /*tp_repr*/
577 0, /*tp_as_number*/
578 0, /*tp_as_sequence*/
579 0, /*tp_as_mapping*/
580 0, /*tp_hash*/
581};
582
583static char poll_doc[] =
584"Returns a polling object, which supports registering and\n\
585unregistering file descriptors, and then polling them for I/O events.";
586
587static PyObject *
588select_poll(PyObject *self, PyObject *args)
589{
590 pollObject *rv;
591
592 if (!PyArg_ParseTuple(args, ":poll"))
593 return NULL;
594 rv = newPollObject();
595 if ( rv == NULL )
596 return NULL;
597 return (PyObject *)rv;
598}
599#endif /* HAVE_POLL */
600
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000601static char select_doc[] =
602"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
603\n\
604Wait until one or more file descriptors are ready for some kind of I/O.\n\
605The first three arguments are lists of file descriptors to be waited for:\n\
606rlist -- wait until ready for reading\n\
607wlist -- wait until ready for writing\n\
608xlist -- wait for an ``exceptional condition''\n\
609If only one kind of condition is required, pass [] for the other lists.\n\
610A file descriptor is either a socket or file object, or a small integer\n\
611gotten from a fileno() method call on one of those.\n\
612\n\
613The optional 4th argument specifies a timeout in seconds; it may be\n\
614a floating point number to specify fractions of seconds. If it is absent\n\
615or None, the call will never time out.\n\
616\n\
617The return value is a tuple of three lists corresponding to the first three\n\
618arguments; each contains the subset of the corresponding file descriptors\n\
619that are ready.\n\
620\n\
621*** IMPORTANT NOTICE ***\n\
622On Windows, only sockets are supported; on Unix, all file descriptors.";
623
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000624static PyMethodDef select_methods[] = {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000625 {"select", select_select, METH_VARARGS, select_doc},
626#ifdef HAVE_POLL
627 {"poll", select_poll, METH_VARARGS, poll_doc},
628#endif /* HAVE_POLL */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000629 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +0000630};
631
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000632static char module_doc[] =
633"This module supports asynchronous I/O on multiple file descriptors.\n\
634\n\
635*** IMPORTANT NOTICE ***\n\
636On Windows, only sockets are supported; on Unix, all file descriptors.";
Guido van Rossumed233a51992-06-23 09:07:03 +0000637
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000638/*
639 * Convenience routine to export an integer value.
640 * For simplicity, errors (which are unlikely anyway) are ignored.
641 */
642
643static void
644insint(PyObject *d, char *name, int value)
645{
646 PyObject *v = PyInt_FromLong((long) value);
647 if (v == NULL) {
648 /* Don't bother reporting this error */
649 PyErr_Clear();
650 }
651 else {
652 PyDict_SetItemString(d, name, v);
653 Py_DECREF(v);
654 }
655}
656
Guido van Rossum3886bb61998-12-04 18:50:17 +0000657DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000658initselect(void)
Guido van Rossumed233a51992-06-23 09:07:03 +0000659{
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000660 PyObject *m, *d;
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000661 m = Py_InitModule3("select", select_methods, module_doc);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000662 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000663 SelectError = PyErr_NewException("select.error", NULL, NULL);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000664 PyDict_SetItemString(d, "error", SelectError);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000665#ifdef HAVE_POLL
666 poll_Type.ob_type = &PyType_Type;
667 insint(d, "POLLIN", POLLIN);
668 insint(d, "POLLPRI", POLLPRI);
669 insint(d, "POLLOUT", POLLOUT);
670 insint(d, "POLLERR", POLLERR);
671 insint(d, "POLLHUP", POLLHUP);
672 insint(d, "POLLNVAL", POLLNVAL);
673
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000674#ifdef POLLRDNORM
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000675 insint(d, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000676#endif
677#ifdef POLLRDBAND
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000678 insint(d, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000679#endif
680#ifdef POLLWRNORM
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000681 insint(d, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000682#endif
683#ifdef POLLWRBAND
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000684 insint(d, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000685#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +0000686#ifdef POLLMSG
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000687 insint(d, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +0000688#endif
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000689#endif /* HAVE_POLL */
Guido van Rossumed233a51992-06-23 09:07:03 +0000690}