blob: 59653dea30f917bd8b80dd626453dfdfafc4dc09 [file] [log] [blame]
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00001/* select - Module containing unix select(2) call.
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002 Under Unix, the file descriptors are small integers.
3 Under Win32, select only exists for sockets, and sockets may
4 have any value except INVALID_SOCKET.
Guido van Rossumbcc20741998-08-04 22:53:56 +00005 Under BeOS, we suffer the same dichotomy as Win32; sockets can be anything
6 >= 0.
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00007*/
Guido van Rossumed233a51992-06-23 09:07:03 +00008
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00009#include "Python.h"
Guido van Rossumed233a51992-06-23 09:07:03 +000010
Tim Petersd92dfe02000-12-12 01:18:41 +000011/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
12 64 is too small (too many people have bumped into that limit).
13 Here we boost it.
14 Users who want even more than the boosted limit should #define
15 FD_SETSIZE higher before this; e.g., via compiler /D switch.
16*/
17#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
18#define FD_SETSIZE 512
19#endif
20
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000021#if defined(HAVE_POLL_H)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000022#include <poll.h>
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000023#elif defined(HAVE_SYS_POLL_H)
24#include <sys/poll.h>
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000025#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000026
Guido van Rossum37273171996-12-09 18:47:43 +000027#ifdef __sgi
28/* This is missing from unistd.h */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000029extern void bzero(void *, int);
Guido van Rossum37273171996-12-09 18:47:43 +000030#endif
31
Guido van Rossumff7e83d1999-08-27 20:39:37 +000032#ifndef DONT_HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000033#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000034#endif
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000035
Andrew MacIntyre7bf68332002-03-03 02:59:16 +000036#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000037#include <sys/time.h>
38#include <utils.h>
39#endif
40
Guido van Rossum6f489d91996-06-28 20:15:15 +000041#ifdef MS_WINDOWS
Thomas Heller7bdabe62002-09-24 17:03:26 +000042#include <winsock.h>
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000043#else
Guido van Rossumbcc20741998-08-04 22:53:56 +000044#ifdef __BEOS__
45#include <net/socket.h>
46#define SOCKET int
47#else
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000048#define SOCKET int
49#endif
Guido van Rossumbcc20741998-08-04 22:53:56 +000050#endif
Guido van Rossumed233a51992-06-23 09:07:03 +000051
Guido van Rossum1ca8bb32001-03-02 06:28:17 +000052
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000053static PyObject *SelectError;
Guido van Rossumed233a51992-06-23 09:07:03 +000054
Barry Warsawc1cb3601996-12-12 22:16:21 +000055/* list of Python objects and their file descriptor */
56typedef struct {
57 PyObject *obj; /* owned reference */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000058 SOCKET fd;
Barry Warsawc1cb3601996-12-12 22:16:21 +000059 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000060} pylist;
61
Barry Warsawc1cb3601996-12-12 22:16:21 +000062static void
Tim Peters4b046c22001-08-16 21:59:46 +000063reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +000064{
65 int i;
Tim Peters4b046c22001-08-16 21:59:46 +000066 for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
Barry Warsawc1cb3601996-12-12 22:16:21 +000067 Py_XDECREF(fd2obj[i].obj);
68 fd2obj[i].obj = NULL;
69 }
70 fd2obj[0].sentinel = -1;
71}
72
73
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000074/* returns -1 and sets the Python exception if an error occurred, otherwise
75 returns a number >= 0
76*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000077static int
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
Thomas Heller106f4c72002-09-24 16:51:00 +0000276#ifdef MS_WINDOWS
277 if (n == SOCKET_ERROR) {
278 PyErr_SetExcFromWindowsErr(SelectError, WSAGetLastError());
279 }
280#else
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000281 if (n < 0) {
282 PyErr_SetFromErrno(SelectError);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000283 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000284#endif
Barry Warsawc1cb3601996-12-12 22:16:21 +0000285 else if (n == 0) {
286 /* optimization */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000287 ifdlist = PyList_New(0);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000288 if (ifdlist) {
289 ret = Py_BuildValue("OOO", ifdlist, ifdlist, ifdlist);
290 Py_DECREF(ifdlist);
291 }
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000292 }
Barry Warsawc1cb3601996-12-12 22:16:21 +0000293 else {
294 /* any of these three calls can raise an exception. it's more
295 convenient to test for this after all three calls... but
296 is that acceptable?
297 */
298 ifdlist = set2list(&ifdset, rfd2obj);
299 ofdlist = set2list(&ofdset, wfd2obj);
300 efdlist = set2list(&efdset, efd2obj);
301 if (PyErr_Occurred())
302 ret = NULL;
303 else
304 ret = Py_BuildValue("OOO", ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000305
Barry Warsawc1cb3601996-12-12 22:16:21 +0000306 Py_DECREF(ifdlist);
307 Py_DECREF(ofdlist);
308 Py_DECREF(efdlist);
309 }
310
311 finally:
312 reap_obj(rfd2obj);
313 reap_obj(wfd2obj);
314 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000315#ifdef SELECT_USES_HEAP
Guido van Rossumd20781b1998-07-02 02:53:36 +0000316 PyMem_DEL(rfd2obj);
317 PyMem_DEL(wfd2obj);
318 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000319#endif /* SELECT_USES_HEAP */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000320 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000321}
322
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000323#ifdef HAVE_POLL
324/*
325 * poll() support
326 */
327
328typedef struct {
329 PyObject_HEAD
330 PyObject *dict;
331 int ufd_uptodate;
332 int ufd_len;
333 struct pollfd *ufds;
334} pollObject;
335
Jeremy Hylton938ace62002-07-17 16:30:39 +0000336static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000337
338/* Update the malloc'ed array of pollfds to match the dictionary
339 contained within a pollObject. Return 1 on success, 0 on an error.
340*/
341
342static int
343update_ufd_array(pollObject *self)
344{
Fred Drakedff3a372001-07-19 21:29:49 +0000345 int i, pos;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000346 PyObject *key, *value;
347
348 self->ufd_len = PyDict_Size(self->dict);
349 PyMem_Resize(self->ufds, struct pollfd, self->ufd_len);
350 if (self->ufds == NULL) {
351 PyErr_NoMemory();
352 return 0;
353 }
354
355 i = pos = 0;
Fred Drakedff3a372001-07-19 21:29:49 +0000356 while (PyDict_Next(self->dict, &pos, &key, &value)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000357 self->ufds[i].fd = PyInt_AsLong(key);
Fred Drakedff3a372001-07-19 21:29:49 +0000358 self->ufds[i].events = (short)PyInt_AsLong(value);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000359 i++;
360 }
361 self->ufd_uptodate = 1;
362 return 1;
363}
364
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000365PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000366"register(fd [, eventmask] ) -> None\n\n\
367Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000368fd -- either an integer, or an object with a fileno() method returning an\n\
369 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000370events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000371
372static PyObject *
373poll_register(pollObject *self, PyObject *args)
374{
375 PyObject *o, *key, *value;
376 int fd, events = POLLIN | POLLPRI | POLLOUT;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000377 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000378
Fred Drake7b87f852001-05-21 03:29:05 +0000379 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000380 return NULL;
381 }
382
383 fd = PyObject_AsFileDescriptor(o);
384 if (fd == -1) return NULL;
385
386 /* Add entry to the internal dictionary: the key is the
387 file descriptor, and the value is the event mask. */
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000388 key = PyInt_FromLong(fd);
389 if (key == NULL)
390 return NULL;
391 value = PyInt_FromLong(events);
392 if (value == NULL) {
393 Py_DECREF(key);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000394 return NULL;
395 }
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000396 err = PyDict_SetItem(self->dict, key, value);
397 Py_DECREF(key);
398 Py_DECREF(value);
399 if (err < 0)
400 return NULL;
401
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000402 self->ufd_uptodate = 0;
403
404 Py_INCREF(Py_None);
405 return Py_None;
406}
407
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000408PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000409"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000410Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000411
412static PyObject *
413poll_unregister(pollObject *self, PyObject *args)
414{
415 PyObject *o, *key;
416 int fd;
417
Fred Drake7b87f852001-05-21 03:29:05 +0000418 if (!PyArg_ParseTuple(args, "O:unregister", &o)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000419 return NULL;
420 }
421
422 fd = PyObject_AsFileDescriptor( o );
423 if (fd == -1)
424 return NULL;
425
426 /* Check whether the fd is already in the array */
427 key = PyInt_FromLong(fd);
428 if (key == NULL)
429 return NULL;
430
431 if (PyDict_DelItem(self->dict, key) == -1) {
432 Py_DECREF(key);
433 /* This will simply raise the KeyError set by PyDict_DelItem
434 if the file descriptor isn't registered. */
435 return NULL;
436 }
437
438 Py_DECREF(key);
439 self->ufd_uptodate = 0;
440
441 Py_INCREF(Py_None);
442 return Py_None;
443}
444
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000445PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000446"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
447Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000448any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000449
450static PyObject *
451poll_poll(pollObject *self, PyObject *args)
452{
453 PyObject *result_list = NULL, *tout = NULL;
454 int timeout = 0, poll_result, i, j;
455 PyObject *value = NULL, *num = NULL;
456
Fred Drake7b87f852001-05-21 03:29:05 +0000457 if (!PyArg_ParseTuple(args, "|O:poll", &tout)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000458 return NULL;
459 }
460
461 /* Check values for timeout */
462 if (tout == NULL || tout == Py_None)
463 timeout = -1;
Neal Norwitz77c72bb2002-07-28 15:12:10 +0000464 else if (!PyNumber_Check(tout)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000465 PyErr_SetString(PyExc_TypeError,
466 "timeout must be an integer or None");
467 return NULL;
468 }
Neal Norwitz77c72bb2002-07-28 15:12:10 +0000469 else {
470 tout = PyNumber_Int(tout);
471 if (!tout)
472 return NULL;
473 timeout = PyInt_AS_LONG(tout);
474 Py_DECREF(tout);
475 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000476
477 /* Ensure the ufd array is up to date */
478 if (!self->ufd_uptodate)
479 if (update_ufd_array(self) == 0)
480 return NULL;
481
482 /* call poll() */
483 Py_BEGIN_ALLOW_THREADS;
484 poll_result = poll(self->ufds, self->ufd_len, timeout);
485 Py_END_ALLOW_THREADS;
486
487 if (poll_result < 0) {
488 PyErr_SetFromErrno(SelectError);
489 return NULL;
490 }
491
492 /* build the result list */
493
494 result_list = PyList_New(poll_result);
495 if (!result_list)
496 return NULL;
497 else {
498 for (i = 0, j = 0; j < poll_result; j++) {
499 /* skip to the next fired descriptor */
500 while (!self->ufds[i].revents) {
501 i++;
502 }
503 /* if we hit a NULL return, set value to NULL
504 and break out of loop; code at end will
505 clean up result_list */
506 value = PyTuple_New(2);
507 if (value == NULL)
508 goto error;
509 num = PyInt_FromLong(self->ufds[i].fd);
510 if (num == NULL) {
511 Py_DECREF(value);
512 goto error;
513 }
514 PyTuple_SET_ITEM(value, 0, num);
515
516 num = PyInt_FromLong(self->ufds[i].revents);
517 if (num == NULL) {
518 Py_DECREF(value);
519 goto error;
520 }
521 PyTuple_SET_ITEM(value, 1, num);
522 if ((PyList_SetItem(result_list, j, value)) == -1) {
523 Py_DECREF(value);
524 goto error;
525 }
526 i++;
527 }
528 }
529 return result_list;
530
531 error:
532 Py_DECREF(result_list);
533 return NULL;
534}
535
536static PyMethodDef poll_methods[] = {
537 {"register", (PyCFunction)poll_register,
538 METH_VARARGS, poll_register_doc},
539 {"unregister", (PyCFunction)poll_unregister,
540 METH_VARARGS, poll_unregister_doc},
541 {"poll", (PyCFunction)poll_poll,
542 METH_VARARGS, poll_poll_doc},
543 {NULL, NULL} /* sentinel */
544};
545
546static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000547newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000548{
549 pollObject *self;
550 self = PyObject_New(pollObject, &poll_Type);
551 if (self == NULL)
552 return NULL;
553 /* ufd_uptodate is a Boolean, denoting whether the
554 array pointed to by ufds matches the contents of the dictionary. */
555 self->ufd_uptodate = 0;
556 self->ufds = NULL;
557 self->dict = PyDict_New();
558 if (self->dict == NULL) {
559 Py_DECREF(self);
560 return NULL;
561 }
562 return self;
563}
564
565static void
566poll_dealloc(pollObject *self)
567{
568 if (self->ufds != NULL)
569 PyMem_DEL(self->ufds);
570 Py_XDECREF(self->dict);
571 PyObject_Del(self);
572}
573
574static PyObject *
575poll_getattr(pollObject *self, char *name)
576{
577 return Py_FindMethod(poll_methods, (PyObject *)self, name);
578}
579
Tim Peters0c322792002-07-17 16:49:03 +0000580static PyTypeObject poll_Type = {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000581 /* The ob_type field must be initialized in the module init function
582 * to be portable to Windows without using C++. */
583 PyObject_HEAD_INIT(NULL)
584 0, /*ob_size*/
Guido van Rossum14648392001-12-08 18:02:58 +0000585 "select.poll", /*tp_name*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000586 sizeof(pollObject), /*tp_basicsize*/
587 0, /*tp_itemsize*/
588 /* methods */
589 (destructor)poll_dealloc, /*tp_dealloc*/
590 0, /*tp_print*/
591 (getattrfunc)poll_getattr, /*tp_getattr*/
592 0, /*tp_setattr*/
593 0, /*tp_compare*/
594 0, /*tp_repr*/
595 0, /*tp_as_number*/
596 0, /*tp_as_sequence*/
597 0, /*tp_as_mapping*/
598 0, /*tp_hash*/
599};
600
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000601PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000602"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000603unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000604
605static PyObject *
606select_poll(PyObject *self, PyObject *args)
607{
608 pollObject *rv;
609
610 if (!PyArg_ParseTuple(args, ":poll"))
611 return NULL;
612 rv = newPollObject();
613 if ( rv == NULL )
614 return NULL;
615 return (PyObject *)rv;
616}
617#endif /* HAVE_POLL */
618
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000619PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000620"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
621\n\
622Wait until one or more file descriptors are ready for some kind of I/O.\n\
623The first three arguments are lists of file descriptors to be waited for:\n\
624rlist -- wait until ready for reading\n\
625wlist -- wait until ready for writing\n\
626xlist -- wait for an ``exceptional condition''\n\
627If only one kind of condition is required, pass [] for the other lists.\n\
628A file descriptor is either a socket or file object, or a small integer\n\
629gotten from a fileno() method call on one of those.\n\
630\n\
631The optional 4th argument specifies a timeout in seconds; it may be\n\
632a floating point number to specify fractions of seconds. If it is absent\n\
633or None, the call will never time out.\n\
634\n\
635The return value is a tuple of three lists corresponding to the first three\n\
636arguments; each contains the subset of the corresponding file descriptors\n\
637that are ready.\n\
638\n\
639*** IMPORTANT NOTICE ***\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000640On Windows, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000641
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000642static PyMethodDef select_methods[] = {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000643 {"select", select_select, METH_VARARGS, select_doc},
644#ifdef HAVE_POLL
645 {"poll", select_poll, METH_VARARGS, poll_doc},
646#endif /* HAVE_POLL */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000647 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +0000648};
649
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000650PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000651"This module supports asynchronous I/O on multiple file descriptors.\n\
652\n\
653*** IMPORTANT NOTICE ***\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000654On Windows, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +0000655
Mark Hammond62b1ab12002-07-23 06:31:15 +0000656PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000657initselect(void)
Guido van Rossumed233a51992-06-23 09:07:03 +0000658{
Fred Drake4baedc12002-04-01 14:53:37 +0000659 PyObject *m;
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000660 m = Py_InitModule3("select", select_methods, module_doc);
Fred Drake4baedc12002-04-01 14:53:37 +0000661
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000662 SelectError = PyErr_NewException("select.error", NULL, NULL);
Fred Drake4baedc12002-04-01 14:53:37 +0000663 Py_INCREF(SelectError);
664 PyModule_AddObject(m, "error", SelectError);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000665#ifdef HAVE_POLL
666 poll_Type.ob_type = &PyType_Type;
Fred Drake4baedc12002-04-01 14:53:37 +0000667 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
668 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
669 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
670 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
671 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
672 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000673
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000674#ifdef POLLRDNORM
Fred Drake4baedc12002-04-01 14:53:37 +0000675 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000676#endif
677#ifdef POLLRDBAND
Fred Drake4baedc12002-04-01 14:53:37 +0000678 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000679#endif
680#ifdef POLLWRNORM
Fred Drake4baedc12002-04-01 14:53:37 +0000681 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000682#endif
683#ifdef POLLWRBAND
Fred Drake4baedc12002-04-01 14:53:37 +0000684 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000685#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +0000686#ifdef POLLMSG
Fred Drake4baedc12002-04-01 14:53:37 +0000687 PyModule_AddIntConstant(m, "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}