blob: 653b713de5ecb0457f494fdaa94a8a83a38eae36 [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 Rossum4f0fbf81996-06-12 04:22:53 +00005*/
Guido van Rossumed233a51992-06-23 09:07:03 +00006
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00007#include "Python.h"
Christian Heimes4fbc72b2008-03-22 00:47:35 +00008#include <structmember.h>
Guido van Rossumed233a51992-06-23 09:07:03 +00009
Thomas Wouters477c8d52006-05-27 19:21:47 +000010#ifdef __APPLE__
11 /* Perform runtime testing for a broken poll on OSX to make it easier
12 * to use the same binary on multiple releases of the OS.
13 */
14#undef HAVE_BROKEN_POLL
15#endif
16
Tim Petersd92dfe02000-12-12 01:18:41 +000017/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
18 64 is too small (too many people have bumped into that limit).
19 Here we boost it.
20 Users who want even more than the boosted limit should #define
21 FD_SETSIZE higher before this; e.g., via compiler /D switch.
22*/
23#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
24#define FD_SETSIZE 512
25#endif
26
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000027#if defined(HAVE_POLL_H)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000028#include <poll.h>
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000029#elif defined(HAVE_SYS_POLL_H)
30#include <sys/poll.h>
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000031#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000032
Guido van Rossum37273171996-12-09 18:47:43 +000033#ifdef __sgi
34/* This is missing from unistd.h */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000035extern void bzero(void *, int);
Guido van Rossum37273171996-12-09 18:47:43 +000036#endif
37
Thomas Wouters0e3f5912006-08-11 14:57:12 +000038#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000039#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000040#endif
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000041
Andrew MacIntyre7bf68332002-03-03 02:59:16 +000042#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000043#include <sys/time.h>
44#include <utils.h>
45#endif
46
Guido van Rossum6f489d91996-06-28 20:15:15 +000047#ifdef MS_WINDOWS
Christian Heimesc36625b2008-01-04 13:33:00 +000048# define WIN32_LEAN_AND_MEAN
Thomas Wouters0e3f5912006-08-11 14:57:12 +000049# include <winsock.h>
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000050#else
Thomas Wouters0e3f5912006-08-11 14:57:12 +000051# define SOCKET int
Skip Montanaroeb33e5a2007-08-17 12:57:41 +000052# if defined(__VMS)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000053# include <socket.h>
54# endif
Guido van Rossumbcc20741998-08-04 22:53:56 +000055#endif
Guido van Rossumed233a51992-06-23 09:07:03 +000056
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000057static PyObject *SelectError;
Guido van Rossumed233a51992-06-23 09:07:03 +000058
Barry Warsawc1cb3601996-12-12 22:16:21 +000059/* list of Python objects and their file descriptor */
60typedef struct {
61 PyObject *obj; /* owned reference */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000062 SOCKET fd;
Barry Warsawc1cb3601996-12-12 22:16:21 +000063 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000064} pylist;
65
Barry Warsawc1cb3601996-12-12 22:16:21 +000066static void
Tim Peters4b046c22001-08-16 21:59:46 +000067reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +000068{
69 int i;
Tim Peters4b046c22001-08-16 21:59:46 +000070 for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
Barry Warsawc1cb3601996-12-12 22:16:21 +000071 Py_XDECREF(fd2obj[i].obj);
72 fd2obj[i].obj = NULL;
73 }
74 fd2obj[0].sentinel = -1;
75}
76
77
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000078/* returns -1 and sets the Python exception if an error occurred, otherwise
79 returns a number >= 0
80*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000081static int
Brett Cannon62dba4c2003-09-10 19:37:42 +000082seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +000083{
Barry Warsawc1cb3601996-12-12 22:16:21 +000084 int i;
85 int max = -1;
86 int index = 0;
Brett Cannon62dba4c2003-09-10 19:37:42 +000087 int len = -1;
88 PyObject* fast_seq = NULL;
Barry Warsawc1cb3601996-12-12 22:16:21 +000089 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000090
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000091 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000092 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000093
Brett Cannon62dba4c2003-09-10 19:37:42 +000094 fast_seq=PySequence_Fast(seq, "arguments 1-3 must be sequences");
95 if (!fast_seq)
96 return -1;
97
98 len = PySequence_Fast_GET_SIZE(fast_seq);
99
Barry Warsawc1cb3601996-12-12 22:16:21 +0000100 for (i = 0; i < len; i++) {
Barry Warsawc1cb3601996-12-12 22:16:21 +0000101 SOCKET v;
102
103 /* any intervening fileno() calls could decr this refcnt */
Brett Cannon62dba4c2003-09-10 19:37:42 +0000104 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Barry Warsaw529fcfe1996-12-16 18:15:34 +0000105 return -1;
Barry Warsaw24c4b3d1996-12-13 23:22:42 +0000106
Barry Warsawc1cb3601996-12-12 22:16:21 +0000107 Py_INCREF(o);
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +0000108 v = PyObject_AsFileDescriptor( o );
109 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000110
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000111#if defined(_MSC_VER)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000112 max = 0; /* not used for Win32 */
113#else /* !_MSC_VER */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000114 if (v < 0 || v >= FD_SETSIZE) {
Barry Warsawc1cb3601996-12-12 22:16:21 +0000115 PyErr_SetString(PyExc_ValueError,
116 "filedescriptor out of range in select()");
117 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000118 }
119 if (v > max)
120 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000121#endif /* _MSC_VER */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000122 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000123
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000124 /* add object and its file descriptor to the list */
125 if (index >= FD_SETSIZE) {
Barry Warsawc1cb3601996-12-12 22:16:21 +0000126 PyErr_SetString(PyExc_ValueError,
127 "too many file descriptors in select()");
128 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000129 }
130 fd2obj[index].obj = o;
131 fd2obj[index].fd = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000132 fd2obj[index].sentinel = 0;
133 fd2obj[++index].sentinel = -1;
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000134 }
Brett Cannon62dba4c2003-09-10 19:37:42 +0000135 Py_DECREF(fast_seq);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000136 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000137
138 finally:
139 Py_XDECREF(o);
Brett Cannon62dba4c2003-09-10 19:37:42 +0000140 Py_DECREF(fast_seq);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000141 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000142}
143
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000144/* returns NULL and sets the Python exception if an error occurred */
145static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000146set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000147{
Barry Warsawc1cb3601996-12-12 22:16:21 +0000148 int i, j, count=0;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000149 PyObject *list, *o;
150 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000151
Barry Warsawc1cb3601996-12-12 22:16:21 +0000152 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000153 if (FD_ISSET(fd2obj[j].fd, set))
Barry Warsawc1cb3601996-12-12 22:16:21 +0000154 count++;
155 }
156 list = PyList_New(count);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000157 if (!list)
158 return NULL;
159
Barry Warsawc1cb3601996-12-12 22:16:21 +0000160 i = 0;
161 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000162 fd = fd2obj[j].fd;
163 if (FD_ISSET(fd, set)) {
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000164#ifndef _MSC_VER
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000165 if (fd > FD_SETSIZE) {
166 PyErr_SetString(PyExc_SystemError,
167 "filedescriptor out of range returned in select()");
Barry Warsawc1cb3601996-12-12 22:16:21 +0000168 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000169 }
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000170#endif
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000171 o = fd2obj[j].obj;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000172 fd2obj[j].obj = NULL;
173 /* transfer ownership */
174 if (PyList_SetItem(list, i, o) < 0)
175 goto finally;
176
177 i++;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000178 }
179 }
180 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000181 finally:
182 Py_DECREF(list);
183 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000184}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000185
Barry Warsawb44740f2001-08-16 16:52:59 +0000186#undef SELECT_USES_HEAP
187#if FD_SETSIZE > 1024
188#define SELECT_USES_HEAP
189#endif /* FD_SETSIZE > 1024 */
190
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000191static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000192select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000193{
Barry Warsawb44740f2001-08-16 16:52:59 +0000194#ifdef SELECT_USES_HEAP
Guido van Rossumd20781b1998-07-02 02:53:36 +0000195 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000196#else /* !SELECT_USES_HEAP */
Tim Peters4b046c22001-08-16 21:59:46 +0000197 /* XXX: All this should probably be implemented as follows:
Barry Warsawb44740f2001-08-16 16:52:59 +0000198 * - find the highest descriptor we're interested in
199 * - add one
200 * - that's the size
201 * See: Stevens, APitUE, $12.5.1
202 */
Tim Peters4b046c22001-08-16 21:59:46 +0000203 pylist rfd2obj[FD_SETSIZE + 1];
204 pylist wfd2obj[FD_SETSIZE + 1];
205 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000206#endif /* SELECT_USES_HEAP */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000207 PyObject *ifdlist, *ofdlist, *efdlist;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000208 PyObject *ret = NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000209 PyObject *tout = Py_None;
210 fd_set ifdset, ofdset, efdset;
211 double timeout;
212 struct timeval tv, *tvp;
Guido van Rossum3262e162000-06-28 21:18:13 +0000213 long seconds;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000214 int imax, omax, emax, max;
215 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000216
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000217 /* convert arguments */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000218 if (!PyArg_UnpackTuple(args, "select", 3, 4,
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000219 &ifdlist, &ofdlist, &efdlist, &tout))
220 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000221
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000222 if (tout == Py_None)
223 tvp = (struct timeval *)0;
Neal Norwitz77c72bb2002-07-28 15:12:10 +0000224 else if (!PyNumber_Check(tout)) {
Barry Warsawc1cb3601996-12-12 22:16:21 +0000225 PyErr_SetString(PyExc_TypeError,
226 "timeout must be a float or None");
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000227 return NULL;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000228 }
Guido van Rossumc7a22701993-11-01 16:27:16 +0000229 else {
Neil Schemenauer47ec6c02002-11-18 16:02:29 +0000230 timeout = PyFloat_AsDouble(tout);
231 if (timeout == -1 && PyErr_Occurred())
Neal Norwitz77c72bb2002-07-28 15:12:10 +0000232 return NULL;
Guido van Rossum3262e162000-06-28 21:18:13 +0000233 if (timeout > (double)LONG_MAX) {
Barry Warsaw2f704552001-08-16 16:55:10 +0000234 PyErr_SetString(PyExc_OverflowError,
235 "timeout period too long");
Guido van Rossum3262e162000-06-28 21:18:13 +0000236 return NULL;
237 }
238 seconds = (long)timeout;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000239 timeout = timeout - (double)seconds;
240 tv.tv_sec = seconds;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000241 tv.tv_usec = (long)(timeout * 1E6);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000242 tvp = &tv;
Guido van Rossumc7a22701993-11-01 16:27:16 +0000243 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000244
Guido van Rossumed233a51992-06-23 09:07:03 +0000245
Barry Warsawb44740f2001-08-16 16:52:59 +0000246#ifdef SELECT_USES_HEAP
Guido van Rossumd20781b1998-07-02 02:53:36 +0000247 /* Allocate memory for the lists */
Tim Peters4b046c22001-08-16 21:59:46 +0000248 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
249 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
250 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
Guido van Rossumd20781b1998-07-02 02:53:36 +0000251 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
Guido van Rossumb18618d2000-05-03 23:44:39 +0000252 if (rfd2obj) PyMem_DEL(rfd2obj);
253 if (wfd2obj) PyMem_DEL(wfd2obj);
254 if (efd2obj) PyMem_DEL(efd2obj);
Tim Peters5f322d32003-02-11 17:18:58 +0000255 return PyErr_NoMemory();
Guido van Rossumd20781b1998-07-02 02:53:36 +0000256 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000257#endif /* SELECT_USES_HEAP */
Brett Cannon62dba4c2003-09-10 19:37:42 +0000258 /* Convert sequences to fd_sets, and get maximum fd number
259 * propagates the Python exception set in seq2set()
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000260 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000261 rfd2obj[0].sentinel = -1;
262 wfd2obj[0].sentinel = -1;
263 efd2obj[0].sentinel = -1;
Brett Cannon62dba4c2003-09-10 19:37:42 +0000264 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000265 goto finally;
Brett Cannon62dba4c2003-09-10 19:37:42 +0000266 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000267 goto finally;
Brett Cannon62dba4c2003-09-10 19:37:42 +0000268 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000269 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000270 max = imax;
271 if (omax > max) max = omax;
272 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000273
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000274 Py_BEGIN_ALLOW_THREADS
275 n = select(max, &ifdset, &ofdset, &efdset, tvp);
276 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000277
Thomas Heller106f4c72002-09-24 16:51:00 +0000278#ifdef MS_WINDOWS
279 if (n == SOCKET_ERROR) {
280 PyErr_SetExcFromWindowsErr(SelectError, WSAGetLastError());
281 }
282#else
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000283 if (n < 0) {
284 PyErr_SetFromErrno(SelectError);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000285 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000286#endif
Barry Warsawc1cb3601996-12-12 22:16:21 +0000287 else if (n == 0) {
288 /* optimization */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000289 ifdlist = PyList_New(0);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000290 if (ifdlist) {
Raymond Hettinger8ae46892003-10-12 19:09:37 +0000291 ret = PyTuple_Pack(3, ifdlist, ifdlist, ifdlist);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000292 Py_DECREF(ifdlist);
293 }
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000294 }
Barry Warsawc1cb3601996-12-12 22:16:21 +0000295 else {
296 /* any of these three calls can raise an exception. it's more
297 convenient to test for this after all three calls... but
298 is that acceptable?
299 */
300 ifdlist = set2list(&ifdset, rfd2obj);
301 ofdlist = set2list(&ofdset, wfd2obj);
302 efdlist = set2list(&efdset, efd2obj);
303 if (PyErr_Occurred())
304 ret = NULL;
305 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +0000306 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000307
Barry Warsawc1cb3601996-12-12 22:16:21 +0000308 Py_DECREF(ifdlist);
309 Py_DECREF(ofdlist);
310 Py_DECREF(efdlist);
311 }
312
313 finally:
314 reap_obj(rfd2obj);
315 reap_obj(wfd2obj);
316 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000317#ifdef SELECT_USES_HEAP
Guido van Rossumd20781b1998-07-02 02:53:36 +0000318 PyMem_DEL(rfd2obj);
319 PyMem_DEL(wfd2obj);
320 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000321#endif /* SELECT_USES_HEAP */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000322 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000323}
324
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000325#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000326/*
327 * poll() support
328 */
329
330typedef struct {
331 PyObject_HEAD
332 PyObject *dict;
333 int ufd_uptodate;
334 int ufd_len;
335 struct pollfd *ufds;
336} pollObject;
337
Jeremy Hylton938ace62002-07-17 16:30:39 +0000338static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000339
340/* Update the malloc'ed array of pollfds to match the dictionary
341 contained within a pollObject. Return 1 on success, 0 on an error.
342*/
343
344static int
345update_ufd_array(pollObject *self)
346{
Martin v. Löwis18e16552006-02-15 17:27:45 +0000347 Py_ssize_t i, pos;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000348 PyObject *key, *value;
349
350 self->ufd_len = PyDict_Size(self->dict);
351 PyMem_Resize(self->ufds, struct pollfd, self->ufd_len);
352 if (self->ufds == NULL) {
353 PyErr_NoMemory();
354 return 0;
355 }
356
357 i = pos = 0;
Fred Drakedff3a372001-07-19 21:29:49 +0000358 while (PyDict_Next(self->dict, &pos, &key, &value)) {
Christian Heimes217cfd12007-12-02 14:31:20 +0000359 self->ufds[i].fd = PyLong_AsLong(key);
360 self->ufds[i].events = (short)PyLong_AsLong(value);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000361 i++;
362 }
363 self->ufd_uptodate = 1;
364 return 1;
365}
366
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000367PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000368"register(fd [, eventmask] ) -> None\n\n\
369Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000370fd -- either an integer, or an object with a fileno() method returning an\n\
371 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000372events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000373
374static PyObject *
375poll_register(pollObject *self, PyObject *args)
376{
377 PyObject *o, *key, *value;
378 int fd, events = POLLIN | POLLPRI | POLLOUT;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000379 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000380
Fred Drake7b87f852001-05-21 03:29:05 +0000381 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000382 return NULL;
383 }
384
385 fd = PyObject_AsFileDescriptor(o);
386 if (fd == -1) return NULL;
387
388 /* Add entry to the internal dictionary: the key is the
389 file descriptor, and the value is the event mask. */
Christian Heimes217cfd12007-12-02 14:31:20 +0000390 key = PyLong_FromLong(fd);
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000391 if (key == NULL)
392 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +0000393 value = PyLong_FromLong(events);
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000394 if (value == NULL) {
395 Py_DECREF(key);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000396 return NULL;
397 }
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000398 err = PyDict_SetItem(self->dict, key, value);
399 Py_DECREF(key);
400 Py_DECREF(value);
401 if (err < 0)
402 return NULL;
403
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000404 self->ufd_uptodate = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000405
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000406 Py_INCREF(Py_None);
407 return Py_None;
408}
409
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000410PyDoc_STRVAR(poll_modify_doc,
411"modify(fd, eventmask) -> None\n\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000412Modify an already registered file descriptor.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000413fd -- either an integer, or an object with a fileno() method returning an\n\
414 int.\n\
415events -- an optional bitmask describing the type of events to check for");
416
417static PyObject *
418poll_modify(pollObject *self, PyObject *args)
419{
420 PyObject *o, *key, *value;
421 int fd, events;
422 int err;
423
424 if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) {
425 return NULL;
426 }
427
428 fd = PyObject_AsFileDescriptor(o);
429 if (fd == -1) return NULL;
430
431 /* Modify registered fd */
432 key = PyLong_FromLong(fd);
433 if (key == NULL)
434 return NULL;
435 if (PyDict_GetItem(self->dict, key) == NULL) {
436 errno = ENOENT;
437 PyErr_SetFromErrno(PyExc_IOError);
438 return NULL;
439 }
440 value = PyLong_FromLong(events);
441 if (value == NULL) {
442 Py_DECREF(key);
443 return NULL;
444 }
445 err = PyDict_SetItem(self->dict, key, value);
446 Py_DECREF(key);
447 Py_DECREF(value);
448 if (err < 0)
449 return NULL;
450
451 self->ufd_uptodate = 0;
452
453 Py_INCREF(Py_None);
454 return Py_None;
455}
456
457
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000458PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000459"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000460Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000461
462static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000463poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000464{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000465 PyObject *key;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000466 int fd;
467
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000468 fd = PyObject_AsFileDescriptor( o );
469 if (fd == -1)
470 return NULL;
471
472 /* Check whether the fd is already in the array */
Christian Heimes217cfd12007-12-02 14:31:20 +0000473 key = PyLong_FromLong(fd);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000474 if (key == NULL)
475 return NULL;
476
477 if (PyDict_DelItem(self->dict, key) == -1) {
478 Py_DECREF(key);
479 /* This will simply raise the KeyError set by PyDict_DelItem
480 if the file descriptor isn't registered. */
481 return NULL;
482 }
483
484 Py_DECREF(key);
485 self->ufd_uptodate = 0;
486
487 Py_INCREF(Py_None);
488 return Py_None;
489}
490
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000491PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000492"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
493Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000494any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000495
496static PyObject *
497poll_poll(pollObject *self, PyObject *args)
498{
499 PyObject *result_list = NULL, *tout = NULL;
500 int timeout = 0, poll_result, i, j;
501 PyObject *value = NULL, *num = NULL;
502
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000503 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000504 return NULL;
505 }
506
507 /* Check values for timeout */
508 if (tout == NULL || tout == Py_None)
509 timeout = -1;
Neal Norwitz77c72bb2002-07-28 15:12:10 +0000510 else if (!PyNumber_Check(tout)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000511 PyErr_SetString(PyExc_TypeError,
512 "timeout must be an integer or None");
513 return NULL;
514 }
Neal Norwitz77c72bb2002-07-28 15:12:10 +0000515 else {
516 tout = PyNumber_Int(tout);
517 if (!tout)
518 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +0000519 timeout = PyLong_AsLong(tout);
Neal Norwitz77c72bb2002-07-28 15:12:10 +0000520 Py_DECREF(tout);
Neal Norwitz0f46bbf2005-11-03 05:00:25 +0000521 if (timeout == -1 && PyErr_Occurred())
522 return NULL;
Neal Norwitz77c72bb2002-07-28 15:12:10 +0000523 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000524
525 /* Ensure the ufd array is up to date */
526 if (!self->ufd_uptodate)
527 if (update_ufd_array(self) == 0)
528 return NULL;
529
530 /* call poll() */
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000531 Py_BEGIN_ALLOW_THREADS
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000532 poll_result = poll(self->ufds, self->ufd_len, timeout);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000533 Py_END_ALLOW_THREADS
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000534
535 if (poll_result < 0) {
536 PyErr_SetFromErrno(SelectError);
537 return NULL;
538 }
539
540 /* build the result list */
541
542 result_list = PyList_New(poll_result);
543 if (!result_list)
544 return NULL;
545 else {
546 for (i = 0, j = 0; j < poll_result; j++) {
547 /* skip to the next fired descriptor */
548 while (!self->ufds[i].revents) {
549 i++;
550 }
551 /* if we hit a NULL return, set value to NULL
552 and break out of loop; code at end will
553 clean up result_list */
554 value = PyTuple_New(2);
555 if (value == NULL)
556 goto error;
Christian Heimes217cfd12007-12-02 14:31:20 +0000557 num = PyLong_FromLong(self->ufds[i].fd);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000558 if (num == NULL) {
559 Py_DECREF(value);
560 goto error;
561 }
562 PyTuple_SET_ITEM(value, 0, num);
563
Andrew M. Kuchlinge5dd1622004-08-07 17:21:27 +0000564 /* The &0xffff is a workaround for AIX. 'revents'
565 is a 16-bit short, and IBM assigned POLLNVAL
566 to be 0x8000, so the conversion to int results
567 in a negative number. See SF bug #923315. */
Christian Heimes217cfd12007-12-02 14:31:20 +0000568 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000569 if (num == NULL) {
570 Py_DECREF(value);
571 goto error;
572 }
573 PyTuple_SET_ITEM(value, 1, num);
574 if ((PyList_SetItem(result_list, j, value)) == -1) {
575 Py_DECREF(value);
576 goto error;
577 }
578 i++;
579 }
580 }
581 return result_list;
582
583 error:
584 Py_DECREF(result_list);
585 return NULL;
586}
587
588static PyMethodDef poll_methods[] = {
589 {"register", (PyCFunction)poll_register,
590 METH_VARARGS, poll_register_doc},
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000591 {"modify", (PyCFunction)poll_modify,
592 METH_VARARGS, poll_modify_doc},
593 {"unregister", (PyCFunction)poll_unregister,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000594 METH_O, poll_unregister_doc},
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000595 {"poll", (PyCFunction)poll_poll,
596 METH_VARARGS, poll_poll_doc},
597 {NULL, NULL} /* sentinel */
598};
599
600static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000601newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000602{
603 pollObject *self;
604 self = PyObject_New(pollObject, &poll_Type);
605 if (self == NULL)
606 return NULL;
607 /* ufd_uptodate is a Boolean, denoting whether the
608 array pointed to by ufds matches the contents of the dictionary. */
609 self->ufd_uptodate = 0;
610 self->ufds = NULL;
611 self->dict = PyDict_New();
612 if (self->dict == NULL) {
613 Py_DECREF(self);
614 return NULL;
615 }
616 return self;
617}
618
619static void
620poll_dealloc(pollObject *self)
621{
622 if (self->ufds != NULL)
623 PyMem_DEL(self->ufds);
624 Py_XDECREF(self->dict);
625 PyObject_Del(self);
626}
627
628static PyObject *
629poll_getattr(pollObject *self, char *name)
630{
631 return Py_FindMethod(poll_methods, (PyObject *)self, name);
632}
633
Tim Peters0c322792002-07-17 16:49:03 +0000634static PyTypeObject poll_Type = {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000635 /* The ob_type field must be initialized in the module init function
636 * to be portable to Windows without using C++. */
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000637 PyVarObject_HEAD_INIT(NULL, 0)
Guido van Rossum14648392001-12-08 18:02:58 +0000638 "select.poll", /*tp_name*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000639 sizeof(pollObject), /*tp_basicsize*/
640 0, /*tp_itemsize*/
641 /* methods */
642 (destructor)poll_dealloc, /*tp_dealloc*/
643 0, /*tp_print*/
644 (getattrfunc)poll_getattr, /*tp_getattr*/
645 0, /*tp_setattr*/
646 0, /*tp_compare*/
647 0, /*tp_repr*/
648 0, /*tp_as_number*/
649 0, /*tp_as_sequence*/
650 0, /*tp_as_mapping*/
651 0, /*tp_hash*/
652};
653
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000654PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000655"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000656unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000657
658static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000659select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000660{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000661 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000662}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000663
664#ifdef __APPLE__
665/*
666 * On some systems poll() sets errno on invalid file descriptors. We test
667 * for this at runtime because this bug may be fixed or introduced between
668 * OS releases.
669 */
670static int select_have_broken_poll(void)
671{
672 int poll_test;
673 int filedes[2];
674
675 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
676
677 /* Create a file descriptor to make invalid */
678 if (pipe(filedes) < 0) {
679 return 1;
680 }
681 poll_struct.fd = filedes[0];
682 close(filedes[0]);
683 close(filedes[1]);
684 poll_test = poll(&poll_struct, 1, 0);
685 if (poll_test < 0) {
686 return 1;
687 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
688 return 1;
689 }
690 return 0;
691}
692#endif /* __APPLE__ */
693
694#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000695
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000696#ifdef HAVE_EPOLL
697/* **************************************************************************
698 * epoll interface for Linux 2.6
699 *
700 * Written by Christian Heimes
701 * Inspired by Twisted's _epoll.pyx and select.poll()
702 */
703
704#ifdef HAVE_SYS_EPOLL_H
705#include <sys/epoll.h>
706#endif
707
708typedef struct {
709 PyObject_HEAD
710 SOCKET epfd; /* epoll control file descriptor */
711} pyEpoll_Object;
712
713static PyTypeObject pyEpoll_Type;
714#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
715
716static PyObject *
717pyepoll_err_closed(void)
718{
719 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
720 return NULL;
721}
722
723static int
724pyepoll_internal_close(pyEpoll_Object *self)
725{
726 int save_errno = 0;
727 if (self->epfd >= 0) {
728 int epfd = self->epfd;
729 self->epfd = -1;
730 Py_BEGIN_ALLOW_THREADS
731 if (close(epfd) < 0)
732 save_errno = errno;
733 Py_END_ALLOW_THREADS
734 }
735 return save_errno;
736}
737
738static PyObject *
739newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
740{
741 pyEpoll_Object *self;
742
743 if (sizehint == -1) {
744 sizehint = FD_SETSIZE-1;
745 }
746 else if (sizehint < 1) {
747 PyErr_Format(PyExc_ValueError,
748 "sizehint must be greater zero, got %d",
749 sizehint);
750 return NULL;
751 }
752
753 assert(type != NULL && type->tp_alloc != NULL);
754 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
755 if (self == NULL)
756 return NULL;
757
758 if (fd == -1) {
759 Py_BEGIN_ALLOW_THREADS
760 self->epfd = epoll_create(sizehint);
761 Py_END_ALLOW_THREADS
762 }
763 else {
764 self->epfd = fd;
765 }
766 if (self->epfd < 0) {
767 Py_DECREF(self);
768 PyErr_SetFromErrno(PyExc_IOError);
769 return NULL;
770 }
771 return (PyObject *)self;
772}
773
774
775static PyObject *
776pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
777{
778 int sizehint = -1;
779 static char *kwlist[] = {"sizehint", NULL};
780
781 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:epoll", kwlist,
782 &sizehint))
783 return NULL;
784
785 return newPyEpoll_Object(type, sizehint, -1);
786}
787
788
789static void
790pyepoll_dealloc(pyEpoll_Object *self)
791{
792 (void)pyepoll_internal_close(self);
793 Py_TYPE(self)->tp_free(self);
794}
795
796static PyObject*
797pyepoll_close(pyEpoll_Object *self)
798{
799 errno = pyepoll_internal_close(self);
800 if (errno < 0) {
801 PyErr_SetFromErrno(PyExc_IOError);
802 return NULL;
803 }
804 Py_RETURN_NONE;
805}
806
807PyDoc_STRVAR(pyepoll_close_doc,
808"close() -> None\n\
809\n\
810Close the epoll control file descriptor. Further operations on the epoll\n\
811object will raise an exception.");
812
813static PyObject*
814pyepoll_get_closed(pyEpoll_Object *self)
815{
816 if (self->epfd < 0)
817 Py_RETURN_TRUE;
818 else
819 Py_RETURN_FALSE;
820}
821
822static PyObject*
823pyepoll_fileno(pyEpoll_Object *self)
824{
825 if (self->epfd < 0)
826 return pyepoll_err_closed();
827 return PyLong_FromLong(self->epfd);
828}
829
830PyDoc_STRVAR(pyepoll_fileno_doc,
831"fileno() -> int\n\
832\n\
833Return the epoll control file descriptor.");
834
835static PyObject*
836pyepoll_fromfd(PyObject *cls, PyObject *args)
837{
838 SOCKET fd;
839
840 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
841 return NULL;
842
843 return newPyEpoll_Object((PyTypeObject*)cls, -1, fd);
844}
845
846PyDoc_STRVAR(pyepoll_fromfd_doc,
847"fromfd(fd) -> epoll\n\
848\n\
849Create an epoll object from a given control fd.");
850
851static PyObject *
852pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
853{
854 struct epoll_event ev;
855 int result;
856 int fd;
857
858 if (epfd < 0)
859 return pyepoll_err_closed();
860
861 fd = PyObject_AsFileDescriptor(pfd);
862 if (fd == -1) {
863 return NULL;
864 }
865
866 switch(op) {
867 case EPOLL_CTL_ADD:
868 case EPOLL_CTL_MOD:
869 ev.events = events;
870 ev.data.fd = fd;
871 Py_BEGIN_ALLOW_THREADS
872 result = epoll_ctl(epfd, op, fd, &ev);
873 Py_END_ALLOW_THREADS
874 break;
875 case EPOLL_CTL_DEL:
876 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
877 * operation required a non-NULL pointer in event, even
878 * though this argument is ignored. */
879 Py_BEGIN_ALLOW_THREADS
880 result = epoll_ctl(epfd, op, fd, &ev);
881 if (errno == EBADF) {
882 /* fd already closed */
883 result = 0;
884 errno = 0;
885 }
886 Py_END_ALLOW_THREADS
887 break;
888 default:
889 result = -1;
890 errno = EINVAL;
891 }
892
893 if (result < 0) {
894 PyErr_SetFromErrno(PyExc_IOError);
895 return NULL;
896 }
897 Py_RETURN_NONE;
898}
899
900static PyObject *
901pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
902{
903 PyObject *pfd;
904 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
905 static char *kwlist[] = {"fd", "eventmask", NULL};
906
907 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
908 &pfd, &events)) {
909 return NULL;
910 }
911
912 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
913}
914
915PyDoc_STRVAR(pyepoll_register_doc,
916"register(fd[, eventmask]) -> bool\n\
917\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000918Registers a new fd or modifies an already registered fd. register() returns\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000919True if a new fd was registered or False if the event mask for fd was modified.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000920fd is the target file descriptor of the operation.\n\
921events is a bit set composed of the various EPOLL constants; the default\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000922is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
923\n\
924The epoll interface supports all file descriptors that support poll.");
925
926static PyObject *
927pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
928{
929 PyObject *pfd;
930 unsigned int events;
931 static char *kwlist[] = {"fd", "eventmask", NULL};
932
933 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
934 &pfd, &events)) {
935 return NULL;
936 }
937
938 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
939}
940
941PyDoc_STRVAR(pyepoll_modify_doc,
942"modify(fd, eventmask) -> None\n\
943\n\
944fd is the target file descriptor of the operation\n\
945events is a bit set composed of the various EPOLL constants");
946
947static PyObject *
948pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
949{
950 PyObject *pfd;
951 static char *kwlist[] = {"fd", NULL};
952
953 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
954 &pfd)) {
955 return NULL;
956 }
957
958 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
959}
960
961PyDoc_STRVAR(pyepoll_unregister_doc,
962"unregister(fd) -> None\n\
963\n\
964fd is the target file descriptor of the operation.");
965
966static PyObject *
967pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
968{
969 double dtimeout = -1.;
970 int timeout;
971 int maxevents = -1;
972 int nfds, i;
973 PyObject *elist = NULL, *etuple = NULL;
974 struct epoll_event *evs = NULL;
975 static char *kwlist[] = {"timeout", "maxevents", NULL};
976
977 if (self->epfd < 0)
978 return pyepoll_err_closed();
979
980 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
981 &dtimeout, &maxevents)) {
982 return NULL;
983 }
984
985 if (dtimeout < 0) {
986 timeout = -1;
987 }
988 else if (dtimeout * 1000.0 > INT_MAX) {
989 PyErr_SetString(PyExc_OverflowError,
990 "timeout is too large");
Christian Heimesf6cd9672008-03-26 13:45:42 +0000991 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000992 }
993 else {
994 timeout = (int)(dtimeout * 1000.0);
995 }
996
997 if (maxevents == -1) {
998 maxevents = FD_SETSIZE-1;
999 }
1000 else if (maxevents < 1) {
1001 PyErr_Format(PyExc_ValueError,
1002 "maxevents must be greater than 0, got %d",
1003 maxevents);
1004 return NULL;
1005 }
1006
1007 evs = PyMem_New(struct epoll_event, maxevents);
1008 if (evs == NULL) {
1009 Py_DECREF(self);
1010 PyErr_NoMemory();
1011 return NULL;
1012 }
1013
1014 Py_BEGIN_ALLOW_THREADS
1015 nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
1016 Py_END_ALLOW_THREADS
1017 if (nfds < 0) {
1018 PyErr_SetFromErrno(PyExc_IOError);
1019 goto error;
1020 }
1021
1022 elist = PyList_New(nfds);
1023 if (elist == NULL) {
1024 goto error;
1025 }
1026
1027 for (i = 0; i < nfds; i++) {
Christian Heimesf6cd9672008-03-26 13:45:42 +00001028 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001029 if (etuple == NULL) {
Christian Heimesf6cd9672008-03-26 13:45:42 +00001030 Py_CLEAR(elist);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001031 goto error;
1032 }
1033 PyList_SET_ITEM(elist, i, etuple);
1034 }
1035
Christian Heimesf6cd9672008-03-26 13:45:42 +00001036 error:
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001037 PyMem_Free(evs);
1038 return elist;
1039}
1040
1041PyDoc_STRVAR(pyepoll_poll_doc,
1042"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1043\n\
1044Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1045in seconds (as float). -1 makes poll wait indefinitely.\n\
1046Up to maxevents are returned to the caller.");
1047
1048static PyMethodDef pyepoll_methods[] = {
1049 {"fromfd", (PyCFunction)pyepoll_fromfd,
1050 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1051 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1052 pyepoll_close_doc},
1053 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1054 pyepoll_fileno_doc},
1055 {"modify", (PyCFunction)pyepoll_modify,
1056 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1057 {"register", (PyCFunction)pyepoll_register,
1058 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1059 {"unregister", (PyCFunction)pyepoll_unregister,
1060 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1061 {"poll", (PyCFunction)pyepoll_poll,
1062 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
1063 {NULL, NULL},
1064};
1065
1066static PyGetSetDef pyepoll_getsetlist[] = {
1067 {"closed", (getter)pyepoll_get_closed, NULL,
1068 "True if the epoll handler is closed"},
1069 {0},
1070};
1071
1072PyDoc_STRVAR(pyepoll_doc,
1073"select.epoll([sizehint=-1])\n\
1074\n\
1075Returns an epolling object\n\
1076\n\
1077sizehint must be a positive integer or -1 for the default size. The\n\
1078sizehint is used to optimize internal data structures. It doesn't limit\n\
1079the maximum number of monitored events.");
1080
1081static PyTypeObject pyEpoll_Type = {
1082 PyVarObject_HEAD_INIT(NULL, 0)
1083 "select.epoll", /* tp_name */
1084 sizeof(pyEpoll_Object), /* tp_basicsize */
1085 0, /* tp_itemsize */
1086 (destructor)pyepoll_dealloc, /* tp_dealloc */
1087 0, /* tp_print */
1088 0, /* tp_getattr */
1089 0, /* tp_setattr */
1090 0, /* tp_compare */
1091 0, /* tp_repr */
1092 0, /* tp_as_number */
1093 0, /* tp_as_sequence */
1094 0, /* tp_as_mapping */
1095 0, /* tp_hash */
1096 0, /* tp_call */
1097 0, /* tp_str */
1098 PyObject_GenericGetAttr, /* tp_getattro */
1099 0, /* tp_setattro */
1100 0, /* tp_as_buffer */
1101 Py_TPFLAGS_DEFAULT, /* tp_flags */
1102 pyepoll_doc, /* tp_doc */
1103 0, /* tp_traverse */
1104 0, /* tp_clear */
1105 0, /* tp_richcompare */
1106 0, /* tp_weaklistoffset */
1107 0, /* tp_iter */
1108 0, /* tp_iternext */
1109 pyepoll_methods, /* tp_methods */
1110 0, /* tp_members */
1111 pyepoll_getsetlist, /* tp_getset */
1112 0, /* tp_base */
1113 0, /* tp_dict */
1114 0, /* tp_descr_get */
1115 0, /* tp_descr_set */
1116 0, /* tp_dictoffset */
1117 0, /* tp_init */
1118 0, /* tp_alloc */
1119 pyepoll_new, /* tp_new */
1120 0, /* tp_free */
1121};
1122
1123#endif /* HAVE_EPOLL */
1124
1125#ifdef HAVE_KQUEUE
1126/* **************************************************************************
1127 * kqueue interface for BSD
1128 *
1129 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1130 * All rights reserved.
1131 *
1132 * Redistribution and use in source and binary forms, with or without
1133 * modification, are permitted provided that the following conditions
1134 * are met:
1135 * 1. Redistributions of source code must retain the above copyright
1136 * notice, this list of conditions and the following disclaimer.
1137 * 2. Redistributions in binary form must reproduce the above copyright
1138 * notice, this list of conditions and the following disclaimer in the
1139 * documentation and/or other materials provided with the distribution.
1140 *
1141 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1142 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1143 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1144 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1145 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1146 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1147 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1148 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1149 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1150 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1151 * SUCH DAMAGE.
1152 */
1153
1154#ifdef HAVE_SYS_EVENT_H
1155#include <sys/event.h>
1156#endif
1157
1158PyDoc_STRVAR(kqueue_event_doc,
1159"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_ADD, fflags=0, data=0, udata=0)\n\
1160\n\
1161This object is the equivalent of the struct kevent for the C API.\n\
1162\n\
1163See the kqueue manpage for more detailed information about the meaning\n\
1164of the arguments.\n\
1165\n\
1166One minor note: while you might hope that udata could store a\n\
1167reference to a python object, it cannot, because it is impossible to\n\
1168keep a proper reference count of the object once it's passed into the\n\
1169kernel. Therefore, I have restricted it to only storing an integer. I\n\
1170recommend ignoring it and simply using the 'ident' field to key off\n\
1171of. You could also set up a dictionary on the python side to store a\n\
1172udata->object mapping.");
1173
1174typedef struct {
1175 PyObject_HEAD
1176 struct kevent e;
1177} kqueue_event_Object;
1178
1179static PyTypeObject kqueue_event_Type;
1180
1181#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1182
1183typedef struct {
1184 PyObject_HEAD
1185 SOCKET kqfd; /* kqueue control fd */
1186} kqueue_queue_Object;
1187
1188static PyTypeObject kqueue_queue_Type;
1189
1190#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1191
1192/* Unfortunately, we can't store python objects in udata, because
1193 * kevents in the kernel can be removed without warning, which would
1194 * forever lose the refcount on the object stored with it.
1195 */
1196
1197#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1198static struct PyMemberDef kqueue_event_members[] = {
1199 {"ident", T_UINT, KQ_OFF(e.ident)},
1200 {"filter", T_SHORT, KQ_OFF(e.filter)},
1201 {"flags", T_USHORT, KQ_OFF(e.flags)},
1202 {"fflags", T_UINT, KQ_OFF(e.fflags)},
1203 {"data", T_INT, KQ_OFF(e.data)},
1204 {"udata", T_INT, KQ_OFF(e.udata)},
1205 {NULL} /* Sentinel */
1206};
1207#undef KQ_OFF
1208
1209static PyObject *
1210kqueue_event_repr(kqueue_event_Object *s)
1211{
1212 char buf[1024];
1213 PyOS_snprintf(
1214 buf, sizeof(buf),
1215 "<select.kevent ident=%lu filter=%d flags=0x%x fflags=0x%x "
1216 "data=0x%lx udata=%p>",
1217 (unsigned long)(s->e.ident), s->e.filter, s->e.flags,
1218 s->e.fflags, (long)(s->e.data), s->e.udata);
1219 return PyString_FromString(buf);
1220}
1221
1222static int
1223kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1224{
1225 PyObject *pfd;
1226 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1227 "data", "udata", NULL};
1228
1229 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
1230
1231 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|hhiii:kevent", kwlist,
1232 &pfd, &(self->e.filter), &(self->e.flags),
1233 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1234 return -1;
1235 }
1236
1237 self->e.ident = PyObject_AsFileDescriptor(pfd);
1238 if (self->e.ident == -1) {
1239 return -1;
1240 }
1241 return 0;
1242}
1243
1244static PyObject *
1245kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
1246 int op)
1247{
1248 int result = 0;
1249
1250 if (!kqueue_event_Check(o)) {
1251 if (op == Py_EQ || op == Py_NE) {
1252 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1253 Py_INCREF(res);
1254 return res;
1255 }
1256 PyErr_Format(PyExc_TypeError,
1257 "can't compare %.200s to %.200s",
1258 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1259 return NULL;
1260 }
1261 if (((result = s->e.ident - o->e.ident) == 0) &&
1262 ((result = s->e.filter - o->e.filter) == 0) &&
1263 ((result = s->e.flags - o->e.flags) == 0) &&
1264 ((result = s->e.fflags - o->e.fflags) == 0) &&
1265 ((result = s->e.data - o->e.data) == 0) &&
1266 ((result = s->e.udata - o->e.udata) == 0)
1267 ) {
1268 result = 0;
1269 }
1270
1271 switch (op) {
1272 case Py_EQ:
1273 result = (result == 0);
1274 break;
1275 case Py_NE:
1276 result = (result != 0);
1277 break;
1278 case Py_LE:
1279 result = (result <= 0);
1280 break;
1281 case Py_GE:
1282 result = (result >= 0);
1283 break;
1284 case Py_LT:
1285 result = (result < 0);
1286 break;
1287 case Py_GT:
1288 result = (result > 0);
1289 break;
1290 }
1291 return PyBool_FromLong(result);
1292}
1293
1294static PyTypeObject kqueue_event_Type = {
1295 PyVarObject_HEAD_INIT(NULL, 0)
1296 "select.kevent", /* tp_name */
1297 sizeof(kqueue_event_Object), /* tp_basicsize */
1298 0, /* tp_itemsize */
1299 0, /* tp_dealloc */
1300 0, /* tp_print */
1301 0, /* tp_getattr */
1302 0, /* tp_setattr */
1303 0, /* tp_compare */
1304 (reprfunc)kqueue_event_repr, /* tp_repr */
1305 0, /* tp_as_number */
1306 0, /* tp_as_sequence */
1307 0, /* tp_as_mapping */
1308 0, /* tp_hash */
1309 0, /* tp_call */
1310 0, /* tp_str */
1311 0, /* tp_getattro */
1312 0, /* tp_setattro */
1313 0, /* tp_as_buffer */
1314 Py_TPFLAGS_DEFAULT, /* tp_flags */
1315 kqueue_event_doc, /* tp_doc */
1316 0, /* tp_traverse */
1317 0, /* tp_clear */
1318 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1319 0, /* tp_weaklistoffset */
1320 0, /* tp_iter */
1321 0, /* tp_iternext */
1322 0, /* tp_methods */
1323 kqueue_event_members, /* tp_members */
1324 0, /* tp_getset */
1325 0, /* tp_base */
1326 0, /* tp_dict */
1327 0, /* tp_descr_get */
1328 0, /* tp_descr_set */
1329 0, /* tp_dictoffset */
1330 (initproc)kqueue_event_init, /* tp_init */
1331 0, /* tp_alloc */
1332 0, /* tp_new */
1333 0, /* tp_free */
1334};
1335
1336static PyObject *
1337kqueue_queue_err_closed(void)
1338{
1339 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1340 return NULL;
1341}
1342
1343static int
1344kqueue_queue_internal_close(kqueue_queue_Object *self)
1345{
1346 int save_errno = 0;
1347 if (self->kqfd >= 0) {
1348 int kqfd = self->kqfd;
1349 self->kqfd = -1;
1350 Py_BEGIN_ALLOW_THREADS
1351 if (close(kqfd) < 0)
1352 save_errno = errno;
1353 Py_END_ALLOW_THREADS
1354 }
1355 return save_errno;
1356}
1357
1358static PyObject *
1359newKqueue_Object(PyTypeObject *type, SOCKET fd)
1360{
1361 kqueue_queue_Object *self;
1362 assert(type != NULL && type->tp_alloc != NULL);
1363 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1364 if (self == NULL) {
1365 return NULL;
1366 }
1367
1368 if (fd == -1) {
1369 Py_BEGIN_ALLOW_THREADS
1370 self->kqfd = kqueue();
1371 Py_END_ALLOW_THREADS
1372 }
1373 else {
1374 self->kqfd = fd;
1375 }
1376 if (self->kqfd < 0) {
1377 Py_DECREF(self);
1378 PyErr_SetFromErrno(PyExc_IOError);
1379 return NULL;
1380 }
1381 return (PyObject *)self;
1382}
1383
1384static PyObject *
1385kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1386{
1387
1388 if ((args != NULL && PyObject_Size(args)) ||
1389 (kwds != NULL && PyObject_Size(kwds))) {
1390 PyErr_SetString(PyExc_ValueError,
1391 "select.kqueue doesn't accept arguments");
1392 return NULL;
1393 }
1394
1395 return newKqueue_Object(type, -1);
1396}
1397
1398static void
1399kqueue_queue_dealloc(kqueue_queue_Object *self)
1400{
1401 kqueue_queue_internal_close(self);
1402 Py_TYPE(self)->tp_free(self);
1403}
1404
1405static PyObject*
1406kqueue_queue_close(kqueue_queue_Object *self)
1407{
1408 errno = kqueue_queue_internal_close(self);
1409 if (errno < 0) {
1410 PyErr_SetFromErrno(PyExc_IOError);
1411 return NULL;
1412 }
1413 Py_RETURN_NONE;
1414}
1415
1416PyDoc_STRVAR(kqueue_queue_close_doc,
1417"close() -> None\n\
1418\n\
1419Close the kqueue control file descriptor. Further operations on the kqueue\n\
1420object will raise an exception.");
1421
1422static PyObject*
1423kqueue_queue_get_closed(kqueue_queue_Object *self)
1424{
1425 if (self->kqfd < 0)
1426 Py_RETURN_TRUE;
1427 else
1428 Py_RETURN_FALSE;
1429}
1430
1431static PyObject*
1432kqueue_queue_fileno(kqueue_queue_Object *self)
1433{
1434 if (self->kqfd < 0)
1435 return kqueue_queue_err_closed();
1436 return PyLong_FromLong(self->kqfd);
1437}
1438
1439PyDoc_STRVAR(kqueue_queue_fileno_doc,
1440"fileno() -> int\n\
1441\n\
1442Return the kqueue control file descriptor.");
1443
1444static PyObject*
1445kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1446{
1447 SOCKET fd;
1448
1449 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1450 return NULL;
1451
1452 return newKqueue_Object((PyTypeObject*)cls, fd);
1453}
1454
1455PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1456"fromfd(fd) -> kqueue\n\
1457\n\
1458Create a kqueue object from a given control fd.");
1459
1460static PyObject *
1461kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1462{
1463 int nevents = 0;
1464 int gotevents = 0;
1465 int nchanges = 0;
1466 int i = 0;
1467 PyObject *otimeout = NULL;
1468 PyObject *ch = NULL;
1469 PyObject *it = NULL, *ei = NULL;
1470 PyObject *result = NULL;
1471 struct kevent *evl = NULL;
1472 struct kevent *chl = NULL;
1473 struct timespec timeoutspec;
1474 struct timespec *ptimeoutspec;
1475
1476 if (self->kqfd < 0)
1477 return kqueue_queue_err_closed();
1478
1479 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1480 return NULL;
1481
1482 if (nevents < 0) {
1483 PyErr_Format(PyExc_ValueError,
1484 "Length of eventlist must be 0 or positive, got %d",
1485 nchanges);
1486 return NULL;
1487 }
1488
1489 if (ch != NULL && ch != Py_None) {
1490 it = PyObject_GetIter(ch);
1491 if (it == NULL) {
1492 PyErr_SetString(PyExc_TypeError,
1493 "changelist is not iterable");
1494 return NULL;
1495 }
1496 nchanges = PyObject_Size(ch);
1497 if (nchanges < 0) {
1498 return NULL;
1499 }
1500 }
1501
1502 if (otimeout == Py_None || otimeout == NULL) {
1503 ptimeoutspec = NULL;
1504 }
1505 else if (PyNumber_Check(otimeout)) {
1506 double timeout;
1507 long seconds;
1508
1509 timeout = PyFloat_AsDouble(otimeout);
1510 if (timeout == -1 && PyErr_Occurred())
1511 return NULL;
1512 if (timeout > (double)LONG_MAX) {
1513 PyErr_SetString(PyExc_OverflowError,
1514 "timeout period too long");
1515 return NULL;
1516 }
1517 if (timeout < 0) {
1518 PyErr_SetString(PyExc_ValueError,
1519 "timeout must be positive or None");
1520 return NULL;
1521 }
1522
1523 seconds = (long)timeout;
1524 timeout = timeout - (double)seconds;
1525 timeoutspec.tv_sec = seconds;
1526 timeoutspec.tv_nsec = (long)(timeout * 1E9);
1527 ptimeoutspec = &timeoutspec;
1528 }
1529 else {
1530 PyErr_Format(PyExc_TypeError,
1531 "timeout argument must be an number "
1532 "or None, got %.200s",
1533 Py_TYPE(otimeout)->tp_name);
1534 return NULL;
1535 }
1536
1537 if (nchanges) {
1538 chl = PyMem_New(struct kevent, nchanges);
1539 if (chl == NULL) {
1540 PyErr_NoMemory();
1541 return NULL;
1542 }
1543 while ((ei = PyIter_Next(it)) != NULL) {
1544 if (!kqueue_event_Check(ei)) {
1545 Py_DECREF(ei);
1546 PyErr_SetString(PyExc_TypeError,
1547 "changelist must be an iterable of "
1548 "select.kevent objects");
1549 goto error;
1550 } else {
1551 chl[i] = ((kqueue_event_Object *)ei)->e;
1552 }
1553 Py_DECREF(ei);
1554 }
1555 }
1556 Py_CLEAR(it);
1557
1558 /* event list */
1559 if (nevents) {
1560 evl = PyMem_New(struct kevent, nevents);
1561 if (evl == NULL) {
1562 PyErr_NoMemory();
1563 return NULL;
1564 }
1565 }
1566
1567 Py_BEGIN_ALLOW_THREADS
1568 gotevents = kevent(self->kqfd, chl, nchanges,
1569 evl, nevents, ptimeoutspec);
1570 Py_END_ALLOW_THREADS
1571
1572 if (gotevents == -1) {
1573 PyErr_SetFromErrno(PyExc_OSError);
1574 goto error;
1575 }
1576
1577 result = PyList_New(gotevents);
1578 if (result == NULL) {
1579 goto error;
1580 }
1581
1582 for (i=0; i < gotevents; i++) {
1583 kqueue_event_Object *ch;
1584
1585 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1586 if (ch == NULL) {
1587 goto error;
1588 }
1589 ch->e = evl[i];
1590 PyList_SET_ITEM(result, i, (PyObject *)ch);
1591 }
1592 PyMem_Free(chl);
1593 PyMem_Free(evl);
1594 return result;
1595
1596 error:
1597 PyMem_Free(chl);
1598 PyMem_Free(evl);
1599 Py_XDECREF(result);
1600 Py_XDECREF(it);
1601 return NULL;
1602}
1603
1604PyDoc_STRVAR(kqueue_queue_control_doc,
1605"control(changelist, max_events=0[, timeout=None]) -> eventlist\n\
1606\n\
1607Calls the kernel kevent function.\n\
1608- changelist must be a list of kevent objects describing the changes\n\
1609 to be made to the kernel's watch list or None.\n\
1610- max_events lets you specify the maximum number of events that the\n\
1611 kernel will return.\n\
1612- timeout is the maximum time to wait in seconds, or else None,\n\
1613 to wait forever. timeout accepts floats for smaller timeouts, too.");
1614
1615
1616static PyMethodDef kqueue_queue_methods[] = {
1617 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
1618 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
1619 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
1620 kqueue_queue_close_doc},
1621 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
1622 kqueue_queue_fileno_doc},
1623 {"control", (PyCFunction)kqueue_queue_control,
1624 METH_VARARGS , kqueue_queue_control_doc},
1625 {NULL, NULL},
1626};
1627
1628static PyGetSetDef kqueue_queue_getsetlist[] = {
1629 {"closed", (getter)kqueue_queue_get_closed, NULL,
1630 "True if the kqueue handler is closed"},
1631 {0},
1632};
1633
1634PyDoc_STRVAR(kqueue_queue_doc,
1635"Kqueue syscall wrapper.\n\
1636\n\
1637For example, to start watching a socket for input:\n\
1638>>> kq = kqueue()\n\
1639>>> sock = socket()\n\
1640>>> sock.connect((host, port))\n\
1641>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
1642\n\
1643To wait one second for it to become writeable:\n\
1644>>> kq.control(None, 1, 1000)\n\
1645\n\
1646To stop listening:\n\
1647>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
1648
1649static PyTypeObject kqueue_queue_Type = {
1650 PyVarObject_HEAD_INIT(NULL, 0)
1651 "select.kqueue", /* tp_name */
1652 sizeof(kqueue_queue_Object), /* tp_basicsize */
1653 0, /* tp_itemsize */
1654 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
1655 0, /* tp_print */
1656 0, /* tp_getattr */
1657 0, /* tp_setattr */
1658 0, /* tp_compare */
1659 0, /* tp_repr */
1660 0, /* tp_as_number */
1661 0, /* tp_as_sequence */
1662 0, /* tp_as_mapping */
1663 0, /* tp_hash */
1664 0, /* tp_call */
1665 0, /* tp_str */
1666 0, /* tp_getattro */
1667 0, /* tp_setattro */
1668 0, /* tp_as_buffer */
1669 Py_TPFLAGS_DEFAULT, /* tp_flags */
1670 kqueue_queue_doc, /* tp_doc */
1671 0, /* tp_traverse */
1672 0, /* tp_clear */
1673 0, /* tp_richcompare */
1674 0, /* tp_weaklistoffset */
1675 0, /* tp_iter */
1676 0, /* tp_iternext */
1677 kqueue_queue_methods, /* tp_methods */
1678 0, /* tp_members */
1679 kqueue_queue_getsetlist, /* tp_getset */
1680 0, /* tp_base */
1681 0, /* tp_dict */
1682 0, /* tp_descr_get */
1683 0, /* tp_descr_set */
1684 0, /* tp_dictoffset */
1685 0, /* tp_init */
1686 0, /* tp_alloc */
1687 kqueue_queue_new, /* tp_new */
1688 0, /* tp_free */
1689};
1690
1691#endif /* HAVE_KQUEUE */
1692/* ************************************************************************ */
1693
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001694PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001695"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
1696\n\
1697Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00001698The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001699rlist -- wait until ready for reading\n\
1700wlist -- wait until ready for writing\n\
1701xlist -- wait for an ``exceptional condition''\n\
1702If only one kind of condition is required, pass [] for the other lists.\n\
1703A file descriptor is either a socket or file object, or a small integer\n\
1704gotten from a fileno() method call on one of those.\n\
1705\n\
1706The optional 4th argument specifies a timeout in seconds; it may be\n\
1707a floating point number to specify fractions of seconds. If it is absent\n\
1708or None, the call will never time out.\n\
1709\n\
1710The return value is a tuple of three lists corresponding to the first three\n\
1711arguments; each contains the subset of the corresponding file descriptors\n\
1712that are ready.\n\
1713\n\
1714*** IMPORTANT NOTICE ***\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001715On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001716descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001717
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00001718static PyMethodDef select_methods[] = {
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001719 {"select", select_select, METH_VARARGS, select_doc},
1720#ifdef HAVE_POLL
1721 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00001722#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001723 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00001724};
1725
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001726PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001727"This module supports asynchronous I/O on multiple file descriptors.\n\
1728\n\
1729*** IMPORTANT NOTICE ***\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001730On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00001731
Mark Hammond62b1ab12002-07-23 06:31:15 +00001732PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001733initselect(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00001734{
Fred Drake4baedc12002-04-01 14:53:37 +00001735 PyObject *m;
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001736 m = Py_InitModule3("select", select_methods, module_doc);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00001737 if (m == NULL)
1738 return;
Fred Drake4baedc12002-04-01 14:53:37 +00001739
Guido van Rossum0cb96de1997-10-01 04:29:29 +00001740 SelectError = PyErr_NewException("select.error", NULL, NULL);
Fred Drake4baedc12002-04-01 14:53:37 +00001741 Py_INCREF(SelectError);
1742 PyModule_AddObject(m, "error", SelectError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001743
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001744#if defined(HAVE_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001745#ifdef __APPLE__
1746 if (select_have_broken_poll()) {
1747 if (PyObject_DelAttrString(m, "poll") == -1) {
1748 PyErr_Clear();
1749 }
1750 } else {
1751#else
1752 {
1753#endif
Christian Heimes90aa7642007-12-19 02:45:37 +00001754 Py_TYPE(&poll_Type) = &PyType_Type;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001755 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
1756 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
1757 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
1758 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
1759 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
1760 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001761
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001762#ifdef POLLRDNORM
Thomas Wouters477c8d52006-05-27 19:21:47 +00001763 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001764#endif
1765#ifdef POLLRDBAND
Thomas Wouters477c8d52006-05-27 19:21:47 +00001766 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001767#endif
1768#ifdef POLLWRNORM
Thomas Wouters477c8d52006-05-27 19:21:47 +00001769 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001770#endif
1771#ifdef POLLWRBAND
Thomas Wouters477c8d52006-05-27 19:21:47 +00001772 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001773#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001774#ifdef POLLMSG
Thomas Wouters477c8d52006-05-27 19:21:47 +00001775 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001776#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00001777 }
1778#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001779
1780#ifdef HAVE_EPOLL
1781 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
1782 if (PyType_Ready(&pyEpoll_Type) < 0)
1783 return;
1784
1785 Py_INCREF(&pyEpoll_Type);
1786 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
1787
1788 PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
1789 PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
1790 PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
1791 PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
1792 PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
1793 PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
1794#ifdef EPOLLONESHOT
1795 /* Kernel 2.6.2+ */
1796 PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
1797#endif
1798 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
1799 PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
1800 PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
1801 PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
1802 PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
1803 PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
1804#endif /* HAVE_EPOLL */
1805
1806#ifdef HAVE_KQUEUE
1807 kqueue_event_Type.tp_new = PyType_GenericNew;
1808 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
1809 if(PyType_Ready(&kqueue_event_Type) < 0)
1810 return;
1811
1812 Py_INCREF(&kqueue_event_Type);
1813 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
1814
1815 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
1816 if(PyType_Ready(&kqueue_queue_Type) < 0)
1817 return;
1818 Py_INCREF(&kqueue_queue_Type);
1819 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
1820
1821 /* event filters */
1822 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
1823 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
1824 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
1825 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
1826 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
1827#ifdef EVFILT_NETDEV
1828 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
1829#endif
1830 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
1831 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
1832
1833 /* event flags */
1834 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
1835 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
1836 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
1837 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
1838 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
1839 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
1840
1841 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
1842 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
1843
1844 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
1845 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
1846
1847 /* READ WRITE filter flag */
1848 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
1849
1850 /* VNODE filter flags */
1851 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
1852 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
1853 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
1854 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
1855 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
1856 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
1857 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
1858
1859 /* PROC filter flags */
1860 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
1861 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
1862 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
1863 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
1864 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
1865
1866 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
1867 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
1868 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
1869
1870 /* NETDEV filter flags */
1871#ifdef EVFILT_NETDEV
1872 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
1873 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
1874 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
1875#endif
1876
1877#endif /* HAVE_KQUEUE */
Guido van Rossumed233a51992-06-23 09:07:03 +00001878}