blob: 2caa0225f4c5ed7c0bdc78db6d67f7134fa66043 [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;
Neal Norwitz77c72bb2002-07-28 15:12:10 +0000211 else if (!PyNumber_Check(tout)) {
Barry Warsawc1cb3601996-12-12 22:16:21 +0000212 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 {
Neal Norwitz77c72bb2002-07-28 15:12:10 +0000217 tout = PyNumber_Float(tout);
218 if (!tout)
219 return NULL;
220 timeout = PyFloat_AS_DOUBLE(tout);
221 Py_DECREF(tout);
Guido van Rossum3262e162000-06-28 21:18:13 +0000222 if (timeout > (double)LONG_MAX) {
Barry Warsaw2f704552001-08-16 16:55:10 +0000223 PyErr_SetString(PyExc_OverflowError,
224 "timeout period too long");
Guido van Rossum3262e162000-06-28 21:18:13 +0000225 return NULL;
226 }
227 seconds = (long)timeout;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000228 timeout = timeout - (double)seconds;
229 tv.tv_sec = seconds;
Guido van Rossum3262e162000-06-28 21:18:13 +0000230 tv.tv_usec = (long)(timeout*1000000.0);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000231 tvp = &tv;
Guido van Rossumc7a22701993-11-01 16:27:16 +0000232 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000233
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000234 /* sanity check first three arguments */
235 if (!PyList_Check(ifdlist) ||
236 !PyList_Check(ofdlist) ||
237 !PyList_Check(efdlist))
238 {
239 PyErr_SetString(PyExc_TypeError,
240 "arguments 1-3 must be lists");
241 return NULL;
242 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000243
Barry Warsawb44740f2001-08-16 16:52:59 +0000244#ifdef SELECT_USES_HEAP
Guido van Rossumd20781b1998-07-02 02:53:36 +0000245 /* Allocate memory for the lists */
Tim Peters4b046c22001-08-16 21:59:46 +0000246 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
247 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
248 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
Guido van Rossumd20781b1998-07-02 02:53:36 +0000249 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
Guido van Rossumb18618d2000-05-03 23:44:39 +0000250 if (rfd2obj) PyMem_DEL(rfd2obj);
251 if (wfd2obj) PyMem_DEL(wfd2obj);
252 if (efd2obj) PyMem_DEL(efd2obj);
Guido van Rossumd20781b1998-07-02 02:53:36 +0000253 return NULL;
254 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000255#endif /* SELECT_USES_HEAP */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000256 /* Convert lists to fd_sets, and get maximum fd number
257 * propagates the Python exception set in list2set()
258 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000259 rfd2obj[0].sentinel = -1;
260 wfd2obj[0].sentinel = -1;
261 efd2obj[0].sentinel = -1;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000262 if ((imax=list2set(ifdlist, &ifdset, rfd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000263 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000264 if ((omax=list2set(ofdlist, &ofdset, wfd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000265 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000266 if ((emax=list2set(efdlist, &efdset, efd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000267 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000268 max = imax;
269 if (omax > max) max = omax;
270 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000271
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000272 Py_BEGIN_ALLOW_THREADS
273 n = select(max, &ifdset, &ofdset, &efdset, tvp);
274 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000275
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000276 if (n < 0) {
277 PyErr_SetFromErrno(SelectError);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000278 }
Barry Warsawc1cb3601996-12-12 22:16:21 +0000279 else if (n == 0) {
280 /* optimization */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000281 ifdlist = PyList_New(0);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000282 if (ifdlist) {
283 ret = Py_BuildValue("OOO", ifdlist, ifdlist, ifdlist);
284 Py_DECREF(ifdlist);
285 }
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000286 }
Barry Warsawc1cb3601996-12-12 22:16:21 +0000287 else {
288 /* any of these three calls can raise an exception. it's more
289 convenient to test for this after all three calls... but
290 is that acceptable?
291 */
292 ifdlist = set2list(&ifdset, rfd2obj);
293 ofdlist = set2list(&ofdset, wfd2obj);
294 efdlist = set2list(&efdset, efd2obj);
295 if (PyErr_Occurred())
296 ret = NULL;
297 else
298 ret = Py_BuildValue("OOO", ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000299
Barry Warsawc1cb3601996-12-12 22:16:21 +0000300 Py_DECREF(ifdlist);
301 Py_DECREF(ofdlist);
302 Py_DECREF(efdlist);
303 }
304
305 finally:
306 reap_obj(rfd2obj);
307 reap_obj(wfd2obj);
308 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000309#ifdef SELECT_USES_HEAP
Guido van Rossumd20781b1998-07-02 02:53:36 +0000310 PyMem_DEL(rfd2obj);
311 PyMem_DEL(wfd2obj);
312 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000313#endif /* SELECT_USES_HEAP */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000314 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000315}
316
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000317#ifdef HAVE_POLL
318/*
319 * poll() support
320 */
321
322typedef struct {
323 PyObject_HEAD
324 PyObject *dict;
325 int ufd_uptodate;
326 int ufd_len;
327 struct pollfd *ufds;
328} pollObject;
329
Jeremy Hylton938ace62002-07-17 16:30:39 +0000330static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000331
332/* Update the malloc'ed array of pollfds to match the dictionary
333 contained within a pollObject. Return 1 on success, 0 on an error.
334*/
335
336static int
337update_ufd_array(pollObject *self)
338{
Fred Drakedff3a372001-07-19 21:29:49 +0000339 int i, pos;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000340 PyObject *key, *value;
341
342 self->ufd_len = PyDict_Size(self->dict);
343 PyMem_Resize(self->ufds, struct pollfd, self->ufd_len);
344 if (self->ufds == NULL) {
345 PyErr_NoMemory();
346 return 0;
347 }
348
349 i = pos = 0;
Fred Drakedff3a372001-07-19 21:29:49 +0000350 while (PyDict_Next(self->dict, &pos, &key, &value)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000351 self->ufds[i].fd = PyInt_AsLong(key);
Fred Drakedff3a372001-07-19 21:29:49 +0000352 self->ufds[i].events = (short)PyInt_AsLong(value);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000353 i++;
354 }
355 self->ufd_uptodate = 1;
356 return 1;
357}
358
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000359PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000360"register(fd [, eventmask] ) -> None\n\n\
361Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000362fd -- either an integer, or an object with a fileno() method returning an\n\
363 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000364events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000365
366static PyObject *
367poll_register(pollObject *self, PyObject *args)
368{
369 PyObject *o, *key, *value;
370 int fd, events = POLLIN | POLLPRI | POLLOUT;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000371 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000372
Fred Drake7b87f852001-05-21 03:29:05 +0000373 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000374 return NULL;
375 }
376
377 fd = PyObject_AsFileDescriptor(o);
378 if (fd == -1) return NULL;
379
380 /* Add entry to the internal dictionary: the key is the
381 file descriptor, and the value is the event mask. */
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000382 key = PyInt_FromLong(fd);
383 if (key == NULL)
384 return NULL;
385 value = PyInt_FromLong(events);
386 if (value == NULL) {
387 Py_DECREF(key);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000388 return NULL;
389 }
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000390 err = PyDict_SetItem(self->dict, key, value);
391 Py_DECREF(key);
392 Py_DECREF(value);
393 if (err < 0)
394 return NULL;
395
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000396 self->ufd_uptodate = 0;
397
398 Py_INCREF(Py_None);
399 return Py_None;
400}
401
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000402PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000403"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000404Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000405
406static PyObject *
407poll_unregister(pollObject *self, PyObject *args)
408{
409 PyObject *o, *key;
410 int fd;
411
Fred Drake7b87f852001-05-21 03:29:05 +0000412 if (!PyArg_ParseTuple(args, "O:unregister", &o)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000413 return NULL;
414 }
415
416 fd = PyObject_AsFileDescriptor( o );
417 if (fd == -1)
418 return NULL;
419
420 /* Check whether the fd is already in the array */
421 key = PyInt_FromLong(fd);
422 if (key == NULL)
423 return NULL;
424
425 if (PyDict_DelItem(self->dict, key) == -1) {
426 Py_DECREF(key);
427 /* This will simply raise the KeyError set by PyDict_DelItem
428 if the file descriptor isn't registered. */
429 return NULL;
430 }
431
432 Py_DECREF(key);
433 self->ufd_uptodate = 0;
434
435 Py_INCREF(Py_None);
436 return Py_None;
437}
438
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000439PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000440"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
441Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000442any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000443
444static PyObject *
445poll_poll(pollObject *self, PyObject *args)
446{
447 PyObject *result_list = NULL, *tout = NULL;
448 int timeout = 0, poll_result, i, j;
449 PyObject *value = NULL, *num = NULL;
450
Fred Drake7b87f852001-05-21 03:29:05 +0000451 if (!PyArg_ParseTuple(args, "|O:poll", &tout)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000452 return NULL;
453 }
454
455 /* Check values for timeout */
456 if (tout == NULL || tout == Py_None)
457 timeout = -1;
Neal Norwitz77c72bb2002-07-28 15:12:10 +0000458 else if (!PyNumber_Check(tout)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000459 PyErr_SetString(PyExc_TypeError,
460 "timeout must be an integer or None");
461 return NULL;
462 }
Neal Norwitz77c72bb2002-07-28 15:12:10 +0000463 else {
464 tout = PyNumber_Int(tout);
465 if (!tout)
466 return NULL;
467 timeout = PyInt_AS_LONG(tout);
468 Py_DECREF(tout);
469 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000470
471 /* Ensure the ufd array is up to date */
472 if (!self->ufd_uptodate)
473 if (update_ufd_array(self) == 0)
474 return NULL;
475
476 /* call poll() */
477 Py_BEGIN_ALLOW_THREADS;
478 poll_result = poll(self->ufds, self->ufd_len, timeout);
479 Py_END_ALLOW_THREADS;
480
481 if (poll_result < 0) {
482 PyErr_SetFromErrno(SelectError);
483 return NULL;
484 }
485
486 /* build the result list */
487
488 result_list = PyList_New(poll_result);
489 if (!result_list)
490 return NULL;
491 else {
492 for (i = 0, j = 0; j < poll_result; j++) {
493 /* skip to the next fired descriptor */
494 while (!self->ufds[i].revents) {
495 i++;
496 }
497 /* if we hit a NULL return, set value to NULL
498 and break out of loop; code at end will
499 clean up result_list */
500 value = PyTuple_New(2);
501 if (value == NULL)
502 goto error;
503 num = PyInt_FromLong(self->ufds[i].fd);
504 if (num == NULL) {
505 Py_DECREF(value);
506 goto error;
507 }
508 PyTuple_SET_ITEM(value, 0, num);
509
510 num = PyInt_FromLong(self->ufds[i].revents);
511 if (num == NULL) {
512 Py_DECREF(value);
513 goto error;
514 }
515 PyTuple_SET_ITEM(value, 1, num);
516 if ((PyList_SetItem(result_list, j, value)) == -1) {
517 Py_DECREF(value);
518 goto error;
519 }
520 i++;
521 }
522 }
523 return result_list;
524
525 error:
526 Py_DECREF(result_list);
527 return NULL;
528}
529
530static PyMethodDef poll_methods[] = {
531 {"register", (PyCFunction)poll_register,
532 METH_VARARGS, poll_register_doc},
533 {"unregister", (PyCFunction)poll_unregister,
534 METH_VARARGS, poll_unregister_doc},
535 {"poll", (PyCFunction)poll_poll,
536 METH_VARARGS, poll_poll_doc},
537 {NULL, NULL} /* sentinel */
538};
539
540static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000541newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000542{
543 pollObject *self;
544 self = PyObject_New(pollObject, &poll_Type);
545 if (self == NULL)
546 return NULL;
547 /* ufd_uptodate is a Boolean, denoting whether the
548 array pointed to by ufds matches the contents of the dictionary. */
549 self->ufd_uptodate = 0;
550 self->ufds = NULL;
551 self->dict = PyDict_New();
552 if (self->dict == NULL) {
553 Py_DECREF(self);
554 return NULL;
555 }
556 return self;
557}
558
559static void
560poll_dealloc(pollObject *self)
561{
562 if (self->ufds != NULL)
563 PyMem_DEL(self->ufds);
564 Py_XDECREF(self->dict);
565 PyObject_Del(self);
566}
567
568static PyObject *
569poll_getattr(pollObject *self, char *name)
570{
571 return Py_FindMethod(poll_methods, (PyObject *)self, name);
572}
573
Tim Peters0c322792002-07-17 16:49:03 +0000574static PyTypeObject poll_Type = {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000575 /* The ob_type field must be initialized in the module init function
576 * to be portable to Windows without using C++. */
577 PyObject_HEAD_INIT(NULL)
578 0, /*ob_size*/
Guido van Rossum14648392001-12-08 18:02:58 +0000579 "select.poll", /*tp_name*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000580 sizeof(pollObject), /*tp_basicsize*/
581 0, /*tp_itemsize*/
582 /* methods */
583 (destructor)poll_dealloc, /*tp_dealloc*/
584 0, /*tp_print*/
585 (getattrfunc)poll_getattr, /*tp_getattr*/
586 0, /*tp_setattr*/
587 0, /*tp_compare*/
588 0, /*tp_repr*/
589 0, /*tp_as_number*/
590 0, /*tp_as_sequence*/
591 0, /*tp_as_mapping*/
592 0, /*tp_hash*/
593};
594
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000595PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000596"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000597unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000598
599static PyObject *
600select_poll(PyObject *self, PyObject *args)
601{
602 pollObject *rv;
603
604 if (!PyArg_ParseTuple(args, ":poll"))
605 return NULL;
606 rv = newPollObject();
607 if ( rv == NULL )
608 return NULL;
609 return (PyObject *)rv;
610}
611#endif /* HAVE_POLL */
612
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000613PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000614"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
615\n\
616Wait until one or more file descriptors are ready for some kind of I/O.\n\
617The first three arguments are lists of file descriptors to be waited for:\n\
618rlist -- wait until ready for reading\n\
619wlist -- wait until ready for writing\n\
620xlist -- wait for an ``exceptional condition''\n\
621If only one kind of condition is required, pass [] for the other lists.\n\
622A file descriptor is either a socket or file object, or a small integer\n\
623gotten from a fileno() method call on one of those.\n\
624\n\
625The optional 4th argument specifies a timeout in seconds; it may be\n\
626a floating point number to specify fractions of seconds. If it is absent\n\
627or None, the call will never time out.\n\
628\n\
629The return value is a tuple of three lists corresponding to the first three\n\
630arguments; each contains the subset of the corresponding file descriptors\n\
631that are ready.\n\
632\n\
633*** IMPORTANT NOTICE ***\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000634On Windows, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000635
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000636static PyMethodDef select_methods[] = {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000637 {"select", select_select, METH_VARARGS, select_doc},
638#ifdef HAVE_POLL
639 {"poll", select_poll, METH_VARARGS, poll_doc},
640#endif /* HAVE_POLL */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000641 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +0000642};
643
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000644PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000645"This module supports asynchronous I/O on multiple file descriptors.\n\
646\n\
647*** IMPORTANT NOTICE ***\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000648On Windows, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +0000649
Mark Hammond62b1ab12002-07-23 06:31:15 +0000650PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000651initselect(void)
Guido van Rossumed233a51992-06-23 09:07:03 +0000652{
Fred Drake4baedc12002-04-01 14:53:37 +0000653 PyObject *m;
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000654 m = Py_InitModule3("select", select_methods, module_doc);
Fred Drake4baedc12002-04-01 14:53:37 +0000655
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000656 SelectError = PyErr_NewException("select.error", NULL, NULL);
Fred Drake4baedc12002-04-01 14:53:37 +0000657 Py_INCREF(SelectError);
658 PyModule_AddObject(m, "error", SelectError);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000659#ifdef HAVE_POLL
660 poll_Type.ob_type = &PyType_Type;
Fred Drake4baedc12002-04-01 14:53:37 +0000661 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
662 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
663 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
664 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
665 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
666 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000667
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000668#ifdef POLLRDNORM
Fred Drake4baedc12002-04-01 14:53:37 +0000669 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000670#endif
671#ifdef POLLRDBAND
Fred Drake4baedc12002-04-01 14:53:37 +0000672 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000673#endif
674#ifdef POLLWRNORM
Fred Drake4baedc12002-04-01 14:53:37 +0000675 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000676#endif
677#ifdef POLLWRBAND
Fred Drake4baedc12002-04-01 14:53:37 +0000678 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000679#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +0000680#ifdef POLLMSG
Fred Drake4baedc12002-04-01 14:53:37 +0000681 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +0000682#endif
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000683#endif /* HAVE_POLL */
Guido van Rossumed233a51992-06-23 09:07:03 +0000684}