blob: a8413fede5cf31b0cea39cc9f619cf3ff16810e3 [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
Jesus Cead8b9ae62011-11-14 19:07:41 +010010#ifdef HAVE_SYS_DEVPOLL_H
11#include <sys/resource.h>
12#include <sys/devpoll.h>
13#include <sys/types.h>
14#include <sys/stat.h>
15#include <fcntl.h>
16#endif
17
Thomas Wouters477c8d52006-05-27 19:21:47 +000018#ifdef __APPLE__
19 /* Perform runtime testing for a broken poll on OSX to make it easier
20 * to use the same binary on multiple releases of the OS.
21 */
22#undef HAVE_BROKEN_POLL
23#endif
24
Tim Petersd92dfe02000-12-12 01:18:41 +000025/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
26 64 is too small (too many people have bumped into that limit).
27 Here we boost it.
28 Users who want even more than the boosted limit should #define
29 FD_SETSIZE higher before this; e.g., via compiler /D switch.
30*/
31#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
32#define FD_SETSIZE 512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000033#endif
Tim Petersd92dfe02000-12-12 01:18:41 +000034
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000035#if defined(HAVE_POLL_H)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000036#include <poll.h>
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000037#elif defined(HAVE_SYS_POLL_H)
38#include <sys/poll.h>
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000039#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000040
Guido van Rossum37273171996-12-09 18:47:43 +000041#ifdef __sgi
42/* This is missing from unistd.h */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000043extern void bzero(void *, int);
Guido van Rossum37273171996-12-09 18:47:43 +000044#endif
45
Thomas Wouters0e3f5912006-08-11 14:57:12 +000046#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000047#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000048#endif
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000049
Andrew MacIntyre7bf68332002-03-03 02:59:16 +000050#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000051#include <sys/time.h>
52#include <utils.h>
53#endif
54
Guido van Rossum6f489d91996-06-28 20:15:15 +000055#ifdef MS_WINDOWS
Christian Heimesc36625b2008-01-04 13:33:00 +000056# define WIN32_LEAN_AND_MEAN
Thomas Wouters0e3f5912006-08-11 14:57:12 +000057# include <winsock.h>
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000058#else
Thomas Wouters0e3f5912006-08-11 14:57:12 +000059# define SOCKET int
Skip Montanaroeb33e5a2007-08-17 12:57:41 +000060# if defined(__VMS)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000061# include <socket.h>
62# endif
Guido van Rossumbcc20741998-08-04 22:53:56 +000063#endif
Guido van Rossumed233a51992-06-23 09:07:03 +000064
Barry Warsawc1cb3601996-12-12 22:16:21 +000065/* list of Python objects and their file descriptor */
66typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000067 PyObject *obj; /* owned reference */
68 SOCKET fd;
69 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000070} pylist;
71
Barry Warsawc1cb3601996-12-12 22:16:21 +000072static void
Tim Peters4b046c22001-08-16 21:59:46 +000073reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +000074{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000075 int i;
76 for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
77 Py_XDECREF(fd2obj[i].obj);
78 fd2obj[i].obj = NULL;
79 }
80 fd2obj[0].sentinel = -1;
Barry Warsawc1cb3601996-12-12 22:16:21 +000081}
82
83
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000084/* returns -1 and sets the Python exception if an error occurred, otherwise
85 returns a number >= 0
86*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000087static int
Brett Cannon62dba4c2003-09-10 19:37:42 +000088seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +000089{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000090 int max = -1;
91 int index = 0;
Victor Stinner0fcab4a2011-01-04 12:59:15 +000092 Py_ssize_t i, len = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000093 PyObject* fast_seq = NULL;
94 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000095
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000096 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
97 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000098
Benjamin Petersone0edb8b2010-06-27 23:49:45 +000099 fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000100 if (!fast_seq)
101 return -1;
102
103 len = PySequence_Fast_GET_SIZE(fast_seq);
104
105 for (i = 0; i < len; i++) {
106 SOCKET v;
107
108 /* any intervening fileno() calls could decr this refcnt */
109 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Brett Cannon62dba4c2003-09-10 19:37:42 +0000110 return -1;
111
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000112 Py_INCREF(o);
113 v = PyObject_AsFileDescriptor( o );
114 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000115
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000116#if defined(_MSC_VER)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000117 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000118#else /* !_MSC_VER */
Charles-François Nataliaa26b272011-08-28 17:51:43 +0200119 if (!_PyIsSelectable_fd(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000120 PyErr_SetString(PyExc_ValueError,
121 "filedescriptor out of range in select()");
122 goto finally;
123 }
124 if (v > max)
125 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000126#endif /* _MSC_VER */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000127 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000128
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000129 /* add object and its file descriptor to the list */
130 if (index >= FD_SETSIZE) {
131 PyErr_SetString(PyExc_ValueError,
132 "too many file descriptors in select()");
133 goto finally;
134 }
135 fd2obj[index].obj = o;
136 fd2obj[index].fd = v;
137 fd2obj[index].sentinel = 0;
138 fd2obj[++index].sentinel = -1;
139 }
140 Py_DECREF(fast_seq);
141 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000142
143 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000144 Py_XDECREF(o);
145 Py_DECREF(fast_seq);
146 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000147}
148
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000149/* returns NULL and sets the Python exception if an error occurred */
150static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000151set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000152{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000153 int i, j, count=0;
154 PyObject *list, *o;
155 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000156
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000157 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
158 if (FD_ISSET(fd2obj[j].fd, set))
159 count++;
160 }
161 list = PyList_New(count);
162 if (!list)
163 return NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000165 i = 0;
166 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
167 fd = fd2obj[j].fd;
168 if (FD_ISSET(fd, set)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000169 o = fd2obj[j].obj;
170 fd2obj[j].obj = NULL;
171 /* transfer ownership */
172 if (PyList_SetItem(list, i, o) < 0)
173 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000174
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000175 i++;
176 }
177 }
178 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000179 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000180 Py_DECREF(list);
181 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000182}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000183
Barry Warsawb44740f2001-08-16 16:52:59 +0000184#undef SELECT_USES_HEAP
185#if FD_SETSIZE > 1024
186#define SELECT_USES_HEAP
187#endif /* FD_SETSIZE > 1024 */
188
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000189static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000190select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000191{
Barry Warsawb44740f2001-08-16 16:52:59 +0000192#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000193 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000194#else /* !SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000195 /* XXX: All this should probably be implemented as follows:
196 * - find the highest descriptor we're interested in
197 * - add one
198 * - that's the size
199 * See: Stevens, APitUE, $12.5.1
200 */
201 pylist rfd2obj[FD_SETSIZE + 1];
202 pylist wfd2obj[FD_SETSIZE + 1];
203 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000204#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000205 PyObject *ifdlist, *ofdlist, *efdlist;
206 PyObject *ret = NULL;
207 PyObject *tout = Py_None;
208 fd_set ifdset, ofdset, efdset;
209 double timeout;
210 struct timeval tv, *tvp;
211 long seconds;
212 int imax, omax, emax, max;
213 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000214
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000215 /* convert arguments */
216 if (!PyArg_UnpackTuple(args, "select", 3, 4,
217 &ifdlist, &ofdlist, &efdlist, &tout))
218 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000219
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000220 if (tout == Py_None)
221 tvp = (struct timeval *)0;
222 else if (!PyNumber_Check(tout)) {
223 PyErr_SetString(PyExc_TypeError,
224 "timeout must be a float or None");
225 return NULL;
226 }
227 else {
228 timeout = PyFloat_AsDouble(tout);
229 if (timeout == -1 && PyErr_Occurred())
230 return NULL;
231 if (timeout > (double)LONG_MAX) {
232 PyErr_SetString(PyExc_OverflowError,
233 "timeout period too long");
234 return NULL;
235 }
Antoine Pitrou131a6412011-04-09 23:49:58 +0200236 if (timeout < 0) {
237 PyErr_SetString(PyExc_ValueError,
238 "timeout must be non-negative");
239 return NULL;
240 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000241 seconds = (long)timeout;
242 timeout = timeout - (double)seconds;
243 tv.tv_sec = seconds;
244 tv.tv_usec = (long)(timeout * 1E6);
245 tvp = &tv;
246 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000247
Guido van Rossumed233a51992-06-23 09:07:03 +0000248
Barry Warsawb44740f2001-08-16 16:52:59 +0000249#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000250 /* Allocate memory for the lists */
251 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
252 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
253 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
254 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
255 if (rfd2obj) PyMem_DEL(rfd2obj);
256 if (wfd2obj) PyMem_DEL(wfd2obj);
257 if (efd2obj) PyMem_DEL(efd2obj);
258 return PyErr_NoMemory();
259 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000260#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000261 /* Convert sequences to fd_sets, and get maximum fd number
262 * propagates the Python exception set in seq2set()
263 */
264 rfd2obj[0].sentinel = -1;
265 wfd2obj[0].sentinel = -1;
266 efd2obj[0].sentinel = -1;
267 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
268 goto finally;
269 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
270 goto finally;
271 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
272 goto finally;
273 max = imax;
274 if (omax > max) max = omax;
275 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000276
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000277 Py_BEGIN_ALLOW_THREADS
278 n = select(max, &ifdset, &ofdset, &efdset, tvp);
279 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000280
Thomas Heller106f4c72002-09-24 16:51:00 +0000281#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000282 if (n == SOCKET_ERROR) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200283 PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000285#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000286 if (n < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200287 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000289#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000290 else {
291 /* any of these three calls can raise an exception. it's more
292 convenient to test for this after all three calls... but
293 is that acceptable?
294 */
295 ifdlist = set2list(&ifdset, rfd2obj);
296 ofdlist = set2list(&ofdset, wfd2obj);
297 efdlist = set2list(&efdset, efd2obj);
298 if (PyErr_Occurred())
299 ret = NULL;
300 else
301 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000302
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000303 Py_DECREF(ifdlist);
304 Py_DECREF(ofdlist);
305 Py_DECREF(efdlist);
306 }
307
Barry Warsawc1cb3601996-12-12 22:16:21 +0000308 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000309 reap_obj(rfd2obj);
310 reap_obj(wfd2obj);
311 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000312#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 PyMem_DEL(rfd2obj);
314 PyMem_DEL(wfd2obj);
315 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000316#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000317 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000318}
319
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000320#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000321/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000322 * poll() support
323 */
324
325typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 PyObject_HEAD
327 PyObject *dict;
328 int ufd_uptodate;
329 int ufd_len;
330 struct pollfd *ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000331} pollObject;
332
Jeremy Hylton938ace62002-07-17 16:30:39 +0000333static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000335/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000336 contained within a pollObject. Return 1 on success, 0 on an error.
337*/
338
339static int
340update_ufd_array(pollObject *self)
341{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000342 Py_ssize_t i, pos;
343 PyObject *key, *value;
344 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000345
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000346 self->ufd_len = PyDict_Size(self->dict);
347 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
348 if (self->ufds == NULL) {
349 self->ufds = old_ufds;
350 PyErr_NoMemory();
351 return 0;
352 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000353
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000354 i = pos = 0;
355 while (PyDict_Next(self->dict, &pos, &key, &value)) {
356 self->ufds[i].fd = PyLong_AsLong(key);
357 self->ufds[i].events = (short)PyLong_AsLong(value);
358 i++;
359 }
360 self->ufd_uptodate = 1;
361 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000362}
363
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000364PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000365"register(fd [, eventmask] ) -> None\n\n\
366Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000367fd -- either an integer, or an object with a fileno() method returning an\n\
368 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000369events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000370
371static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000372poll_register(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000373{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 PyObject *o, *key, *value;
375 int fd, events = POLLIN | POLLPRI | POLLOUT;
376 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000377
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
379 return NULL;
380 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 fd = PyObject_AsFileDescriptor(o);
383 if (fd == -1) return NULL;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000384
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000385 /* Add entry to the internal dictionary: the key is the
386 file descriptor, and the value is the event mask. */
387 key = PyLong_FromLong(fd);
388 if (key == NULL)
389 return NULL;
390 value = PyLong_FromLong(events);
391 if (value == NULL) {
392 Py_DECREF(key);
393 return NULL;
394 }
395 err = PyDict_SetItem(self->dict, key, value);
396 Py_DECREF(key);
397 Py_DECREF(value);
398 if (err < 0)
399 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000400
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000401 self->ufd_uptodate = 0;
402
403 Py_INCREF(Py_None);
404 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000405}
406
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000407PyDoc_STRVAR(poll_modify_doc,
408"modify(fd, eventmask) -> None\n\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000409Modify an already registered file descriptor.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000410fd -- either an integer, or an object with a fileno() method returning an\n\
411 int.\n\
412events -- an optional bitmask describing the type of events to check for");
413
414static PyObject *
415poll_modify(pollObject *self, PyObject *args)
416{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000417 PyObject *o, *key, *value;
418 int fd, events;
419 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000421 if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) {
422 return NULL;
423 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000424
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000425 fd = PyObject_AsFileDescriptor(o);
426 if (fd == -1) return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000427
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000428 /* Modify registered fd */
429 key = PyLong_FromLong(fd);
430 if (key == NULL)
431 return NULL;
432 if (PyDict_GetItem(self->dict, key) == NULL) {
433 errno = ENOENT;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200434 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000435 return NULL;
436 }
437 value = PyLong_FromLong(events);
438 if (value == NULL) {
439 Py_DECREF(key);
440 return NULL;
441 }
442 err = PyDict_SetItem(self->dict, key, value);
443 Py_DECREF(key);
444 Py_DECREF(value);
445 if (err < 0)
446 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000447
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000448 self->ufd_uptodate = 0;
449
450 Py_INCREF(Py_None);
451 return Py_None;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000452}
453
454
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000455PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000456"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000457Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000458
459static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000460poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000461{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000462 PyObject *key;
463 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000465 fd = PyObject_AsFileDescriptor( o );
466 if (fd == -1)
467 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000468
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000469 /* Check whether the fd is already in the array */
470 key = PyLong_FromLong(fd);
471 if (key == NULL)
472 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000473
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000474 if (PyDict_DelItem(self->dict, key) == -1) {
475 Py_DECREF(key);
476 /* This will simply raise the KeyError set by PyDict_DelItem
477 if the file descriptor isn't registered. */
478 return NULL;
479 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000481 Py_DECREF(key);
482 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 Py_INCREF(Py_None);
485 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000486}
487
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000488PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000489"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
490Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000491any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000492
493static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000495{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000496 PyObject *result_list = NULL, *tout = NULL;
497 int timeout = 0, poll_result, i, j;
498 PyObject *value = NULL, *num = NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000500 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
501 return NULL;
502 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 /* Check values for timeout */
505 if (tout == NULL || tout == Py_None)
506 timeout = -1;
507 else if (!PyNumber_Check(tout)) {
508 PyErr_SetString(PyExc_TypeError,
509 "timeout must be an integer or None");
510 return NULL;
511 }
512 else {
513 tout = PyNumber_Long(tout);
514 if (!tout)
515 return NULL;
516 timeout = PyLong_AsLong(tout);
517 Py_DECREF(tout);
518 if (timeout == -1 && PyErr_Occurred())
519 return NULL;
520 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000521
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000522 /* Ensure the ufd array is up to date */
523 if (!self->ufd_uptodate)
524 if (update_ufd_array(self) == 0)
525 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000526
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000527 /* call poll() */
528 Py_BEGIN_ALLOW_THREADS
529 poll_result = poll(self->ufds, self->ufd_len, timeout);
530 Py_END_ALLOW_THREADS
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000531
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000532 if (poll_result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200533 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000534 return NULL;
535 }
536
537 /* build the result list */
538
539 result_list = PyList_New(poll_result);
540 if (!result_list)
541 return NULL;
542 else {
543 for (i = 0, j = 0; j < poll_result; j++) {
544 /* skip to the next fired descriptor */
545 while (!self->ufds[i].revents) {
546 i++;
547 }
548 /* if we hit a NULL return, set value to NULL
549 and break out of loop; code at end will
550 clean up result_list */
551 value = PyTuple_New(2);
552 if (value == NULL)
553 goto error;
554 num = PyLong_FromLong(self->ufds[i].fd);
555 if (num == NULL) {
556 Py_DECREF(value);
557 goto error;
558 }
559 PyTuple_SET_ITEM(value, 0, num);
560
561 /* The &0xffff is a workaround for AIX. 'revents'
562 is a 16-bit short, and IBM assigned POLLNVAL
563 to be 0x8000, so the conversion to int results
564 in a negative number. See SF bug #923315. */
565 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
566 if (num == NULL) {
567 Py_DECREF(value);
568 goto error;
569 }
570 PyTuple_SET_ITEM(value, 1, num);
571 if ((PyList_SetItem(result_list, j, value)) == -1) {
572 Py_DECREF(value);
573 goto error;
574 }
575 i++;
576 }
577 }
578 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000579
580 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581 Py_DECREF(result_list);
582 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000583}
584
585static PyMethodDef poll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000586 {"register", (PyCFunction)poll_register,
587 METH_VARARGS, poll_register_doc},
588 {"modify", (PyCFunction)poll_modify,
589 METH_VARARGS, poll_modify_doc},
590 {"unregister", (PyCFunction)poll_unregister,
591 METH_O, poll_unregister_doc},
592 {"poll", (PyCFunction)poll_poll,
593 METH_VARARGS, poll_poll_doc},
594 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000595};
596
597static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000598newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000599{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000600 pollObject *self;
601 self = PyObject_New(pollObject, &poll_Type);
602 if (self == NULL)
603 return NULL;
604 /* ufd_uptodate is a Boolean, denoting whether the
605 array pointed to by ufds matches the contents of the dictionary. */
606 self->ufd_uptodate = 0;
607 self->ufds = NULL;
608 self->dict = PyDict_New();
609 if (self->dict == NULL) {
610 Py_DECREF(self);
611 return NULL;
612 }
613 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000614}
615
616static void
617poll_dealloc(pollObject *self)
618{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000619 if (self->ufds != NULL)
620 PyMem_DEL(self->ufds);
621 Py_XDECREF(self->dict);
622 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000623}
624
Tim Peters0c322792002-07-17 16:49:03 +0000625static PyTypeObject poll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 /* The ob_type field must be initialized in the module init function
627 * to be portable to Windows without using C++. */
628 PyVarObject_HEAD_INIT(NULL, 0)
629 "select.poll", /*tp_name*/
630 sizeof(pollObject), /*tp_basicsize*/
631 0, /*tp_itemsize*/
632 /* methods */
633 (destructor)poll_dealloc, /*tp_dealloc*/
634 0, /*tp_print*/
635 0, /*tp_getattr*/
636 0, /*tp_setattr*/
637 0, /*tp_reserved*/
638 0, /*tp_repr*/
639 0, /*tp_as_number*/
640 0, /*tp_as_sequence*/
641 0, /*tp_as_mapping*/
642 0, /*tp_hash*/
643 0, /*tp_call*/
644 0, /*tp_str*/
645 0, /*tp_getattro*/
646 0, /*tp_setattro*/
647 0, /*tp_as_buffer*/
648 Py_TPFLAGS_DEFAULT, /*tp_flags*/
649 0, /*tp_doc*/
650 0, /*tp_traverse*/
651 0, /*tp_clear*/
652 0, /*tp_richcompare*/
653 0, /*tp_weaklistoffset*/
654 0, /*tp_iter*/
655 0, /*tp_iternext*/
656 poll_methods, /*tp_methods*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000657};
658
Jesus Cead8b9ae62011-11-14 19:07:41 +0100659#ifdef HAVE_SYS_DEVPOLL_H
660typedef struct {
661 PyObject_HEAD
662 int fd_devpoll;
663 int max_n_fds;
664 int n_fds;
665 struct pollfd *fds;
666} devpollObject;
667
668static PyTypeObject devpoll_Type;
669
670static int devpoll_flush(devpollObject *self)
671{
672 int size, n;
673
674 if (!self->n_fds) return 0;
675
676 size = sizeof(struct pollfd)*self->n_fds;
677 self->n_fds = 0;
678
679 Py_BEGIN_ALLOW_THREADS
680 n = write(self->fd_devpoll, self->fds, size);
681 Py_END_ALLOW_THREADS
682
683 if (n == -1 ) {
684 PyErr_SetFromErrno(PyExc_IOError);
685 return -1;
686 }
687 if (n < size) {
688 /*
689 ** Data writed to /dev/poll is a binary data structure. It is not
690 ** clear what to do if a partial write occurred. For now, raise
691 ** an exception and see if we actually found this problem in
692 ** the wild.
693 ** See http://bugs.python.org/issue6397.
694 */
695 PyErr_Format(PyExc_IOError, "failed to write all pollfds. "
696 "Please, report at http://bugs.python.org/. "
697 "Data to report: Size tried: %d, actual size written: %d.",
698 size, n);
699 return -1;
700 }
701 return 0;
702}
703
704static PyObject *
705internal_devpoll_register(devpollObject *self, PyObject *args, int remove)
706{
707 PyObject *o;
708 int fd, events = POLLIN | POLLPRI | POLLOUT;
709
710 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
711 return NULL;
712 }
713
714 fd = PyObject_AsFileDescriptor(o);
715 if (fd == -1) return NULL;
716
717 if (remove) {
718 self->fds[self->n_fds].fd = fd;
719 self->fds[self->n_fds].events = POLLREMOVE;
720
721 if (++self->n_fds == self->max_n_fds) {
722 if (devpoll_flush(self))
723 return NULL;
724 }
725 }
726
727 self->fds[self->n_fds].fd = fd;
728 self->fds[self->n_fds].events = events;
729
730 if (++self->n_fds == self->max_n_fds) {
731 if (devpoll_flush(self))
732 return NULL;
733 }
734
735 Py_RETURN_NONE;
736}
737
738PyDoc_STRVAR(devpoll_register_doc,
739"register(fd [, eventmask] ) -> None\n\n\
740Register a file descriptor with the polling object.\n\
741fd -- either an integer, or an object with a fileno() method returning an\n\
742 int.\n\
743events -- an optional bitmask describing the type of events to check for");
744
745static PyObject *
746devpoll_register(devpollObject *self, PyObject *args)
747{
748 return internal_devpoll_register(self, args, 0);
749}
750
751PyDoc_STRVAR(devpoll_modify_doc,
752"modify(fd[, eventmask]) -> None\n\n\
753Modify a possible already registered file descriptor.\n\
754fd -- either an integer, or an object with a fileno() method returning an\n\
755 int.\n\
756events -- an optional bitmask describing the type of events to check for");
757
758static PyObject *
759devpoll_modify(devpollObject *self, PyObject *args)
760{
761 return internal_devpoll_register(self, args, 1);
762}
763
764
765PyDoc_STRVAR(devpoll_unregister_doc,
766"unregister(fd) -> None\n\n\
767Remove a file descriptor being tracked by the polling object.");
768
769static PyObject *
770devpoll_unregister(devpollObject *self, PyObject *o)
771{
772 int fd;
773
774 fd = PyObject_AsFileDescriptor( o );
775 if (fd == -1)
776 return NULL;
777
778 self->fds[self->n_fds].fd = fd;
779 self->fds[self->n_fds].events = POLLREMOVE;
780
781 if (++self->n_fds == self->max_n_fds) {
782 if (devpoll_flush(self))
783 return NULL;
784 }
785
786 Py_RETURN_NONE;
787}
788
789PyDoc_STRVAR(devpoll_poll_doc,
790"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
791Polls the set of registered file descriptors, returning a list containing \n\
792any descriptors that have events or errors to report.");
793
794static PyObject *
795devpoll_poll(devpollObject *self, PyObject *args)
796{
797 struct dvpoll dvp;
798 PyObject *result_list = NULL, *tout = NULL;
799 int poll_result, i;
800 long timeout;
801 PyObject *value, *num1, *num2;
802
803 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
804 return NULL;
805 }
806
807 /* Check values for timeout */
808 if (tout == NULL || tout == Py_None)
809 timeout = -1;
810 else if (!PyNumber_Check(tout)) {
811 PyErr_SetString(PyExc_TypeError,
812 "timeout must be an integer or None");
813 return NULL;
814 }
815 else {
816 tout = PyNumber_Long(tout);
817 if (!tout)
818 return NULL;
819 timeout = PyLong_AsLong(tout);
820 Py_DECREF(tout);
821 if (timeout == -1 && PyErr_Occurred())
822 return NULL;
823 }
824
825 if ((timeout < -1) || (timeout > INT_MAX)) {
826 PyErr_SetString(PyExc_OverflowError,
827 "timeout is out of range");
828 return NULL;
829 }
830
831 if (devpoll_flush(self))
832 return NULL;
833
834 dvp.dp_fds = self->fds;
835 dvp.dp_nfds = self->max_n_fds;
836 dvp.dp_timeout = timeout;
837
838 /* call devpoll() */
839 Py_BEGIN_ALLOW_THREADS
840 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
841 Py_END_ALLOW_THREADS
842
843 if (poll_result < 0) {
844 PyErr_SetFromErrno(PyExc_IOError);
845 return NULL;
846 }
847
848 /* build the result list */
849
850 result_list = PyList_New(poll_result);
851 if (!result_list)
852 return NULL;
853 else {
854 for (i = 0; i < poll_result; i++) {
855 num1 = PyLong_FromLong(self->fds[i].fd);
856 num2 = PyLong_FromLong(self->fds[i].revents);
857 if ((num1 == NULL) || (num2 == NULL)) {
858 Py_XDECREF(num1);
859 Py_XDECREF(num2);
860 goto error;
861 }
862 value = PyTuple_Pack(2, num1, num2);
863 Py_DECREF(num1);
864 Py_DECREF(num2);
865 if (value == NULL)
866 goto error;
867 if ((PyList_SetItem(result_list, i, value)) == -1) {
868 Py_DECREF(value);
869 goto error;
870 }
871 }
872 }
873
874 return result_list;
875
876 error:
877 Py_DECREF(result_list);
878 return NULL;
879}
880
881static PyMethodDef devpoll_methods[] = {
882 {"register", (PyCFunction)devpoll_register,
883 METH_VARARGS, devpoll_register_doc},
884 {"modify", (PyCFunction)devpoll_modify,
885 METH_VARARGS, devpoll_modify_doc},
886 {"unregister", (PyCFunction)devpoll_unregister,
887 METH_O, devpoll_unregister_doc},
888 {"poll", (PyCFunction)devpoll_poll,
889 METH_VARARGS, devpoll_poll_doc},
890 {NULL, NULL} /* sentinel */
891};
892
893static devpollObject *
894newDevPollObject(void)
895{
896 devpollObject *self;
897 int fd_devpoll, limit_result;
898 struct pollfd *fds;
899 struct rlimit limit;
900
901 Py_BEGIN_ALLOW_THREADS
902 /*
903 ** If we try to process more that getrlimit()
904 ** fds, the kernel will give an error, so
905 ** we set the limit here. It is a dynamic
906 ** value, because we can change rlimit() anytime.
907 */
908 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
909 if (limit_result != -1)
910 fd_devpoll = open("/dev/poll", O_RDWR);
911 Py_END_ALLOW_THREADS
912
913 if (limit_result == -1) {
914 PyErr_SetFromErrno(PyExc_OSError);
915 return NULL;
916 }
917 if (fd_devpoll == -1) {
918 PyErr_SetFromErrnoWithFilename(PyExc_IOError, "/dev/poll");
919 return NULL;
920 }
921
922 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
923 if (fds == NULL) {
924 close(fd_devpoll);
925 PyErr_NoMemory();
926 return NULL;
927 }
928
929 self = PyObject_New(devpollObject, &devpoll_Type);
930 if (self == NULL) {
931 close(fd_devpoll);
932 PyMem_DEL(fds);
933 return NULL;
934 }
935 self->fd_devpoll = fd_devpoll;
936 self->max_n_fds = limit.rlim_cur;
937 self->n_fds = 0;
938 self->fds = fds;
939
940 return self;
941}
942
943static void
944devpoll_dealloc(devpollObject *self)
945{
946 Py_BEGIN_ALLOW_THREADS
947 close(self->fd_devpoll);
948 Py_END_ALLOW_THREADS
949
950 PyMem_DEL(self->fds);
951
952 PyObject_Del(self);
953}
954
955static PyTypeObject devpoll_Type = {
956 /* The ob_type field must be initialized in the module init function
957 * to be portable to Windows without using C++. */
958 PyVarObject_HEAD_INIT(NULL, 0)
959 "select.devpoll", /*tp_name*/
960 sizeof(devpollObject), /*tp_basicsize*/
961 0, /*tp_itemsize*/
962 /* methods */
963 (destructor)devpoll_dealloc, /*tp_dealloc*/
964 0, /*tp_print*/
965 0, /*tp_getattr*/
966 0, /*tp_setattr*/
967 0, /*tp_reserved*/
968 0, /*tp_repr*/
969 0, /*tp_as_number*/
970 0, /*tp_as_sequence*/
971 0, /*tp_as_mapping*/
972 0, /*tp_hash*/
973 0, /*tp_call*/
974 0, /*tp_str*/
975 0, /*tp_getattro*/
976 0, /*tp_setattro*/
977 0, /*tp_as_buffer*/
978 Py_TPFLAGS_DEFAULT, /*tp_flags*/
979 0, /*tp_doc*/
980 0, /*tp_traverse*/
981 0, /*tp_clear*/
982 0, /*tp_richcompare*/
983 0, /*tp_weaklistoffset*/
984 0, /*tp_iter*/
985 0, /*tp_iternext*/
986 devpoll_methods, /*tp_methods*/
987};
988#endif /* HAVE_SYS_DEVPOLL_H */
989
990
991
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000992PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000993"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000994unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000995
996static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000997select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000998{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000999 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001000}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001001
Jesus Cead8b9ae62011-11-14 19:07:41 +01001002#ifdef HAVE_SYS_DEVPOLL_H
1003PyDoc_STRVAR(devpoll_doc,
1004"Returns a polling object, which supports registering and\n\
1005unregistering file descriptors, and then polling them for I/O events.");
1006
1007static PyObject *
1008select_devpoll(PyObject *self, PyObject *unused)
1009{
1010 return (PyObject *)newDevPollObject();
1011}
1012#endif
1013
1014
Thomas Wouters477c8d52006-05-27 19:21:47 +00001015#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001016/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001017 * On some systems poll() sets errno on invalid file descriptors. We test
1018 * for this at runtime because this bug may be fixed or introduced between
1019 * OS releases.
1020 */
1021static int select_have_broken_poll(void)
1022{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023 int poll_test;
1024 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001025
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001026 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001027
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001028 /* Create a file descriptor to make invalid */
1029 if (pipe(filedes) < 0) {
1030 return 1;
1031 }
1032 poll_struct.fd = filedes[0];
1033 close(filedes[0]);
1034 close(filedes[1]);
1035 poll_test = poll(&poll_struct, 1, 0);
1036 if (poll_test < 0) {
1037 return 1;
1038 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1039 return 1;
1040 }
1041 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001042}
1043#endif /* __APPLE__ */
1044
1045#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001046
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001047#ifdef HAVE_EPOLL
1048/* **************************************************************************
1049 * epoll interface for Linux 2.6
1050 *
1051 * Written by Christian Heimes
1052 * Inspired by Twisted's _epoll.pyx and select.poll()
1053 */
1054
1055#ifdef HAVE_SYS_EPOLL_H
1056#include <sys/epoll.h>
1057#endif
1058
1059typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 PyObject_HEAD
1061 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001062} pyEpoll_Object;
1063
1064static PyTypeObject pyEpoll_Type;
1065#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
1066
1067static PyObject *
1068pyepoll_err_closed(void)
1069{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001070 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
1071 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001072}
1073
1074static int
1075pyepoll_internal_close(pyEpoll_Object *self)
1076{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077 int save_errno = 0;
1078 if (self->epfd >= 0) {
1079 int epfd = self->epfd;
1080 self->epfd = -1;
1081 Py_BEGIN_ALLOW_THREADS
1082 if (close(epfd) < 0)
1083 save_errno = errno;
1084 Py_END_ALLOW_THREADS
1085 }
1086 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001087}
1088
1089static PyObject *
Benjamin Peterson95c16622011-12-27 15:36:32 -06001090newPyEpoll_Object(PyTypeObject *type, int sizehint, int flags, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001091{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001092 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001093
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001094 assert(type != NULL && type->tp_alloc != NULL);
1095 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
1096 if (self == NULL)
1097 return NULL;
1098
1099 if (fd == -1) {
1100 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001101#ifdef HAVE_EPOLL_CREATE1
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001102 self->epfd = epoll_create1(flags);
Benjamin Peterson95c16622011-12-27 15:36:32 -06001103#else
1104 self->epfd = epoll_create(sizehint);
1105#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001106 Py_END_ALLOW_THREADS
1107 }
1108 else {
1109 self->epfd = fd;
1110 }
1111 if (self->epfd < 0) {
1112 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001113 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001114 return NULL;
1115 }
1116 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001117}
1118
1119
1120static PyObject *
1121pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1122{
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001123 int flags = 0, sizehint = 0;
1124 static char *kwlist[] = {"sizehint", "flags", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001125
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001126 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:epoll", kwlist,
1127 &sizehint, &flags))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001128 return NULL;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001129 if (sizehint < 0) {
1130 PyErr_SetString(PyExc_ValueError, "negative sizehint");
1131 return NULL;
1132 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001133
Benjamin Peterson95c16622011-12-27 15:36:32 -06001134 return newPyEpoll_Object(type, sizehint, flags, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001135}
1136
1137
1138static void
1139pyepoll_dealloc(pyEpoll_Object *self)
1140{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001141 (void)pyepoll_internal_close(self);
1142 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001143}
1144
1145static PyObject*
1146pyepoll_close(pyEpoll_Object *self)
1147{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001148 errno = pyepoll_internal_close(self);
1149 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001150 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001151 return NULL;
1152 }
1153 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001154}
1155
1156PyDoc_STRVAR(pyepoll_close_doc,
1157"close() -> None\n\
1158\n\
1159Close the epoll control file descriptor. Further operations on the epoll\n\
1160object will raise an exception.");
1161
1162static PyObject*
1163pyepoll_get_closed(pyEpoll_Object *self)
1164{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001165 if (self->epfd < 0)
1166 Py_RETURN_TRUE;
1167 else
1168 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001169}
1170
1171static PyObject*
1172pyepoll_fileno(pyEpoll_Object *self)
1173{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001174 if (self->epfd < 0)
1175 return pyepoll_err_closed();
1176 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001177}
1178
1179PyDoc_STRVAR(pyepoll_fileno_doc,
1180"fileno() -> int\n\
1181\n\
1182Return the epoll control file descriptor.");
1183
1184static PyObject*
1185pyepoll_fromfd(PyObject *cls, PyObject *args)
1186{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001187 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001188
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001189 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1190 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001191
Benjamin Peterson95c16622011-12-27 15:36:32 -06001192 return newPyEpoll_Object((PyTypeObject*)cls, FD_SETSIZE - 1, 0, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001193}
1194
1195PyDoc_STRVAR(pyepoll_fromfd_doc,
1196"fromfd(fd) -> epoll\n\
1197\n\
1198Create an epoll object from a given control fd.");
1199
1200static PyObject *
1201pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
1202{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001203 struct epoll_event ev;
1204 int result;
1205 int fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001207 if (epfd < 0)
1208 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001209
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001210 fd = PyObject_AsFileDescriptor(pfd);
1211 if (fd == -1) {
1212 return NULL;
1213 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001214
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001215 switch(op) {
1216 case EPOLL_CTL_ADD:
1217 case EPOLL_CTL_MOD:
1218 ev.events = events;
1219 ev.data.fd = fd;
1220 Py_BEGIN_ALLOW_THREADS
1221 result = epoll_ctl(epfd, op, fd, &ev);
1222 Py_END_ALLOW_THREADS
1223 break;
1224 case EPOLL_CTL_DEL:
1225 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1226 * operation required a non-NULL pointer in event, even
1227 * though this argument is ignored. */
1228 Py_BEGIN_ALLOW_THREADS
1229 result = epoll_ctl(epfd, op, fd, &ev);
1230 if (errno == EBADF) {
1231 /* fd already closed */
1232 result = 0;
1233 errno = 0;
1234 }
1235 Py_END_ALLOW_THREADS
1236 break;
1237 default:
1238 result = -1;
1239 errno = EINVAL;
1240 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001241
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001242 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001243 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001244 return NULL;
1245 }
1246 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001247}
1248
1249static PyObject *
1250pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1251{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 PyObject *pfd;
1253 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
1254 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001256 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
1257 &pfd, &events)) {
1258 return NULL;
1259 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001261 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001262}
1263
1264PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl222569d2010-08-02 20:47:56 +00001265"register(fd[, eventmask]) -> None\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001266\n\
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001267Registers a new fd or raises an OSError if the fd is already registered.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001268fd is the target file descriptor of the operation.\n\
1269events is a bit set composed of the various EPOLL constants; the default\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001270is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
1271\n\
1272The epoll interface supports all file descriptors that support poll.");
1273
1274static PyObject *
1275pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1276{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001277 PyObject *pfd;
1278 unsigned int events;
1279 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001280
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001281 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
1282 &pfd, &events)) {
1283 return NULL;
1284 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001285
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001286 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001287}
1288
1289PyDoc_STRVAR(pyepoll_modify_doc,
1290"modify(fd, eventmask) -> None\n\
1291\n\
1292fd is the target file descriptor of the operation\n\
1293events is a bit set composed of the various EPOLL constants");
1294
1295static PyObject *
1296pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1297{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001298 PyObject *pfd;
1299 static char *kwlist[] = {"fd", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001300
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
1302 &pfd)) {
1303 return NULL;
1304 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001305
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001306 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001307}
1308
1309PyDoc_STRVAR(pyepoll_unregister_doc,
1310"unregister(fd) -> None\n\
1311\n\
1312fd is the target file descriptor of the operation.");
1313
1314static PyObject *
1315pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1316{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001317 double dtimeout = -1.;
1318 int timeout;
1319 int maxevents = -1;
1320 int nfds, i;
1321 PyObject *elist = NULL, *etuple = NULL;
1322 struct epoll_event *evs = NULL;
1323 static char *kwlist[] = {"timeout", "maxevents", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 if (self->epfd < 0)
1326 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001327
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001328 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
1329 &dtimeout, &maxevents)) {
1330 return NULL;
1331 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001332
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001333 if (dtimeout < 0) {
1334 timeout = -1;
1335 }
1336 else if (dtimeout * 1000.0 > INT_MAX) {
1337 PyErr_SetString(PyExc_OverflowError,
1338 "timeout is too large");
1339 return NULL;
1340 }
1341 else {
1342 timeout = (int)(dtimeout * 1000.0);
1343 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001345 if (maxevents == -1) {
1346 maxevents = FD_SETSIZE-1;
1347 }
1348 else if (maxevents < 1) {
1349 PyErr_Format(PyExc_ValueError,
1350 "maxevents must be greater than 0, got %d",
1351 maxevents);
1352 return NULL;
1353 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001355 evs = PyMem_New(struct epoll_event, maxevents);
1356 if (evs == NULL) {
1357 Py_DECREF(self);
1358 PyErr_NoMemory();
1359 return NULL;
1360 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001361
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001362 Py_BEGIN_ALLOW_THREADS
1363 nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
1364 Py_END_ALLOW_THREADS
1365 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001366 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001367 goto error;
1368 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001369
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001370 elist = PyList_New(nfds);
1371 if (elist == NULL) {
1372 goto error;
1373 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 for (i = 0; i < nfds; i++) {
1376 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
1377 if (etuple == NULL) {
1378 Py_CLEAR(elist);
1379 goto error;
1380 }
1381 PyList_SET_ITEM(elist, i, etuple);
1382 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001383
Christian Heimesf6cd9672008-03-26 13:45:42 +00001384 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001385 PyMem_Free(evs);
1386 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001387}
1388
1389PyDoc_STRVAR(pyepoll_poll_doc,
1390"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1391\n\
1392Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1393in seconds (as float). -1 makes poll wait indefinitely.\n\
1394Up to maxevents are returned to the caller.");
1395
1396static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001397 {"fromfd", (PyCFunction)pyepoll_fromfd,
1398 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1399 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1400 pyepoll_close_doc},
1401 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1402 pyepoll_fileno_doc},
1403 {"modify", (PyCFunction)pyepoll_modify,
1404 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1405 {"register", (PyCFunction)pyepoll_register,
1406 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1407 {"unregister", (PyCFunction)pyepoll_unregister,
1408 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1409 {"poll", (PyCFunction)pyepoll_poll,
1410 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
1411 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001412};
1413
1414static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001415 {"closed", (getter)pyepoll_get_closed, NULL,
1416 "True if the epoll handler is closed"},
1417 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001418};
1419
1420PyDoc_STRVAR(pyepoll_doc,
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001421"select.epoll(sizehint=-1, flags=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001422\n\
1423Returns an epolling object\n\
1424\n\
1425sizehint must be a positive integer or -1 for the default size. The\n\
1426sizehint is used to optimize internal data structures. It doesn't limit\n\
1427the maximum number of monitored events.");
1428
1429static PyTypeObject pyEpoll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001430 PyVarObject_HEAD_INIT(NULL, 0)
1431 "select.epoll", /* tp_name */
1432 sizeof(pyEpoll_Object), /* tp_basicsize */
1433 0, /* tp_itemsize */
1434 (destructor)pyepoll_dealloc, /* tp_dealloc */
1435 0, /* tp_print */
1436 0, /* tp_getattr */
1437 0, /* tp_setattr */
1438 0, /* tp_reserved */
1439 0, /* tp_repr */
1440 0, /* tp_as_number */
1441 0, /* tp_as_sequence */
1442 0, /* tp_as_mapping */
1443 0, /* tp_hash */
1444 0, /* tp_call */
1445 0, /* tp_str */
1446 PyObject_GenericGetAttr, /* tp_getattro */
1447 0, /* tp_setattro */
1448 0, /* tp_as_buffer */
1449 Py_TPFLAGS_DEFAULT, /* tp_flags */
1450 pyepoll_doc, /* tp_doc */
1451 0, /* tp_traverse */
1452 0, /* tp_clear */
1453 0, /* tp_richcompare */
1454 0, /* tp_weaklistoffset */
1455 0, /* tp_iter */
1456 0, /* tp_iternext */
1457 pyepoll_methods, /* tp_methods */
1458 0, /* tp_members */
1459 pyepoll_getsetlist, /* tp_getset */
1460 0, /* tp_base */
1461 0, /* tp_dict */
1462 0, /* tp_descr_get */
1463 0, /* tp_descr_set */
1464 0, /* tp_dictoffset */
1465 0, /* tp_init */
1466 0, /* tp_alloc */
1467 pyepoll_new, /* tp_new */
1468 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001469};
1470
1471#endif /* HAVE_EPOLL */
1472
1473#ifdef HAVE_KQUEUE
1474/* **************************************************************************
1475 * kqueue interface for BSD
1476 *
1477 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1478 * All rights reserved.
1479 *
1480 * Redistribution and use in source and binary forms, with or without
1481 * modification, are permitted provided that the following conditions
1482 * are met:
1483 * 1. Redistributions of source code must retain the above copyright
1484 * notice, this list of conditions and the following disclaimer.
1485 * 2. Redistributions in binary form must reproduce the above copyright
1486 * notice, this list of conditions and the following disclaimer in the
1487 * documentation and/or other materials provided with the distribution.
1488 *
1489 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1490 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1491 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1492 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1493 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1494 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1495 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1496 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1497 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1498 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1499 * SUCH DAMAGE.
1500 */
1501
1502#ifdef HAVE_SYS_EVENT_H
1503#include <sys/event.h>
1504#endif
1505
1506PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001507"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001508\n\
1509This object is the equivalent of the struct kevent for the C API.\n\
1510\n\
1511See the kqueue manpage for more detailed information about the meaning\n\
1512of the arguments.\n\
1513\n\
1514One minor note: while you might hope that udata could store a\n\
1515reference to a python object, it cannot, because it is impossible to\n\
1516keep a proper reference count of the object once it's passed into the\n\
1517kernel. Therefore, I have restricted it to only storing an integer. I\n\
1518recommend ignoring it and simply using the 'ident' field to key off\n\
1519of. You could also set up a dictionary on the python side to store a\n\
1520udata->object mapping.");
1521
1522typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001523 PyObject_HEAD
1524 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001525} kqueue_event_Object;
1526
1527static PyTypeObject kqueue_event_Type;
1528
1529#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1530
1531typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001532 PyObject_HEAD
1533 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001534} kqueue_queue_Object;
1535
1536static PyTypeObject kqueue_queue_Type;
1537
1538#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1539
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001540#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1541# error uintptr_t does not match void *!
1542#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1543# define T_UINTPTRT T_ULONGLONG
1544# define T_INTPTRT T_LONGLONG
1545# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1546# define UINTPTRT_FMT_UNIT "K"
1547# define INTPTRT_FMT_UNIT "L"
1548#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1549# define T_UINTPTRT T_ULONG
1550# define T_INTPTRT T_LONG
1551# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1552# define UINTPTRT_FMT_UNIT "k"
1553# define INTPTRT_FMT_UNIT "l"
1554#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1555# define T_UINTPTRT T_UINT
1556# define T_INTPTRT T_INT
1557# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1558# define UINTPTRT_FMT_UNIT "I"
1559# define INTPTRT_FMT_UNIT "i"
1560#else
1561# error uintptr_t does not match int, long, or long long!
1562#endif
1563
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001564/* Unfortunately, we can't store python objects in udata, because
1565 * kevents in the kernel can be removed without warning, which would
1566 * forever lose the refcount on the object stored with it.
1567 */
1568
1569#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1570static struct PyMemberDef kqueue_event_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001571 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1572 {"filter", T_SHORT, KQ_OFF(e.filter)},
1573 {"flags", T_USHORT, KQ_OFF(e.flags)},
1574 {"fflags", T_UINT, KQ_OFF(e.fflags)},
1575 {"data", T_INTPTRT, KQ_OFF(e.data)},
1576 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1577 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001578};
1579#undef KQ_OFF
1580
1581static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001582
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001583kqueue_event_repr(kqueue_event_Object *s)
1584{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001585 char buf[1024];
1586 PyOS_snprintf(
1587 buf, sizeof(buf),
1588 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1589 "data=0x%zd udata=%p>",
1590 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1591 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1592 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001593}
1594
1595static int
1596kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1597{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001598 PyObject *pfd;
1599 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1600 "data", "udata", NULL};
1601 static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001602
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001603 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001604
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001605 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1606 &pfd, &(self->e.filter), &(self->e.flags),
1607 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1608 return -1;
1609 }
1610
1611 if (PyLong_Check(pfd)) {
1612 self->e.ident = PyLong_AsUintptr_t(pfd);
1613 }
1614 else {
1615 self->e.ident = PyObject_AsFileDescriptor(pfd);
1616 }
1617 if (PyErr_Occurred()) {
1618 return -1;
1619 }
1620 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001621}
1622
1623static PyObject *
1624kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001625 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001626{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001627 Py_intptr_t result = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001628
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 if (!kqueue_event_Check(o)) {
1630 if (op == Py_EQ || op == Py_NE) {
1631 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1632 Py_INCREF(res);
1633 return res;
1634 }
1635 PyErr_Format(PyExc_TypeError,
1636 "can't compare %.200s to %.200s",
1637 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1638 return NULL;
1639 }
1640 if (((result = s->e.ident - o->e.ident) == 0) &&
1641 ((result = s->e.filter - o->e.filter) == 0) &&
1642 ((result = s->e.flags - o->e.flags) == 0) &&
1643 ((result = s->e.fflags - o->e.fflags) == 0) &&
1644 ((result = s->e.data - o->e.data) == 0) &&
1645 ((result = s->e.udata - o->e.udata) == 0)
1646 ) {
1647 result = 0;
1648 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001649
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001650 switch (op) {
1651 case Py_EQ:
1652 result = (result == 0);
1653 break;
1654 case Py_NE:
1655 result = (result != 0);
1656 break;
1657 case Py_LE:
1658 result = (result <= 0);
1659 break;
1660 case Py_GE:
1661 result = (result >= 0);
1662 break;
1663 case Py_LT:
1664 result = (result < 0);
1665 break;
1666 case Py_GT:
1667 result = (result > 0);
1668 break;
1669 }
1670 return PyBool_FromLong((long)result);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001671}
1672
1673static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001674 PyVarObject_HEAD_INIT(NULL, 0)
1675 "select.kevent", /* tp_name */
1676 sizeof(kqueue_event_Object), /* tp_basicsize */
1677 0, /* tp_itemsize */
1678 0, /* tp_dealloc */
1679 0, /* tp_print */
1680 0, /* tp_getattr */
1681 0, /* tp_setattr */
1682 0, /* tp_reserved */
1683 (reprfunc)kqueue_event_repr, /* tp_repr */
1684 0, /* tp_as_number */
1685 0, /* tp_as_sequence */
1686 0, /* tp_as_mapping */
1687 0, /* tp_hash */
1688 0, /* tp_call */
1689 0, /* tp_str */
1690 0, /* tp_getattro */
1691 0, /* tp_setattro */
1692 0, /* tp_as_buffer */
1693 Py_TPFLAGS_DEFAULT, /* tp_flags */
1694 kqueue_event_doc, /* tp_doc */
1695 0, /* tp_traverse */
1696 0, /* tp_clear */
1697 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1698 0, /* tp_weaklistoffset */
1699 0, /* tp_iter */
1700 0, /* tp_iternext */
1701 0, /* tp_methods */
1702 kqueue_event_members, /* tp_members */
1703 0, /* tp_getset */
1704 0, /* tp_base */
1705 0, /* tp_dict */
1706 0, /* tp_descr_get */
1707 0, /* tp_descr_set */
1708 0, /* tp_dictoffset */
1709 (initproc)kqueue_event_init, /* tp_init */
1710 0, /* tp_alloc */
1711 0, /* tp_new */
1712 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001713};
1714
1715static PyObject *
1716kqueue_queue_err_closed(void)
1717{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001718 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1719 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001720}
1721
1722static int
1723kqueue_queue_internal_close(kqueue_queue_Object *self)
1724{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001725 int save_errno = 0;
1726 if (self->kqfd >= 0) {
1727 int kqfd = self->kqfd;
1728 self->kqfd = -1;
1729 Py_BEGIN_ALLOW_THREADS
1730 if (close(kqfd) < 0)
1731 save_errno = errno;
1732 Py_END_ALLOW_THREADS
1733 }
1734 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001735}
1736
1737static PyObject *
1738newKqueue_Object(PyTypeObject *type, SOCKET fd)
1739{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001740 kqueue_queue_Object *self;
1741 assert(type != NULL && type->tp_alloc != NULL);
1742 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1743 if (self == NULL) {
1744 return NULL;
1745 }
1746
1747 if (fd == -1) {
1748 Py_BEGIN_ALLOW_THREADS
1749 self->kqfd = kqueue();
1750 Py_END_ALLOW_THREADS
1751 }
1752 else {
1753 self->kqfd = fd;
1754 }
1755 if (self->kqfd < 0) {
1756 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001757 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001758 return NULL;
1759 }
1760 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001761}
1762
1763static PyObject *
1764kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1765{
1766
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001767 if ((args != NULL && PyObject_Size(args)) ||
1768 (kwds != NULL && PyObject_Size(kwds))) {
1769 PyErr_SetString(PyExc_ValueError,
1770 "select.kqueue doesn't accept arguments");
1771 return NULL;
1772 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001773
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001774 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001775}
1776
1777static void
1778kqueue_queue_dealloc(kqueue_queue_Object *self)
1779{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001780 kqueue_queue_internal_close(self);
1781 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001782}
1783
1784static PyObject*
1785kqueue_queue_close(kqueue_queue_Object *self)
1786{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001787 errno = kqueue_queue_internal_close(self);
1788 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001789 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001790 return NULL;
1791 }
1792 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001793}
1794
1795PyDoc_STRVAR(kqueue_queue_close_doc,
1796"close() -> None\n\
1797\n\
1798Close the kqueue control file descriptor. Further operations on the kqueue\n\
1799object will raise an exception.");
1800
1801static PyObject*
1802kqueue_queue_get_closed(kqueue_queue_Object *self)
1803{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001804 if (self->kqfd < 0)
1805 Py_RETURN_TRUE;
1806 else
1807 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001808}
1809
1810static PyObject*
1811kqueue_queue_fileno(kqueue_queue_Object *self)
1812{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001813 if (self->kqfd < 0)
1814 return kqueue_queue_err_closed();
1815 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001816}
1817
1818PyDoc_STRVAR(kqueue_queue_fileno_doc,
1819"fileno() -> int\n\
1820\n\
1821Return the kqueue control file descriptor.");
1822
1823static PyObject*
1824kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1825{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001826 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001827
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001828 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1829 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001830
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001831 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001832}
1833
1834PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1835"fromfd(fd) -> kqueue\n\
1836\n\
1837Create a kqueue object from a given control fd.");
1838
1839static PyObject *
1840kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1841{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001842 int nevents = 0;
1843 int gotevents = 0;
1844 int nchanges = 0;
1845 int i = 0;
1846 PyObject *otimeout = NULL;
1847 PyObject *ch = NULL;
1848 PyObject *it = NULL, *ei = NULL;
1849 PyObject *result = NULL;
1850 struct kevent *evl = NULL;
1851 struct kevent *chl = NULL;
1852 struct timespec timeoutspec;
1853 struct timespec *ptimeoutspec;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001854
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001855 if (self->kqfd < 0)
1856 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001857
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001858 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1859 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001860
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001861 if (nevents < 0) {
1862 PyErr_Format(PyExc_ValueError,
1863 "Length of eventlist must be 0 or positive, got %d",
1864 nevents);
1865 return NULL;
1866 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001868 if (otimeout == Py_None || otimeout == NULL) {
1869 ptimeoutspec = NULL;
1870 }
1871 else if (PyNumber_Check(otimeout)) {
1872 double timeout;
1873 long seconds;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001874
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001875 timeout = PyFloat_AsDouble(otimeout);
1876 if (timeout == -1 && PyErr_Occurred())
1877 return NULL;
1878 if (timeout > (double)LONG_MAX) {
1879 PyErr_SetString(PyExc_OverflowError,
1880 "timeout period too long");
1881 return NULL;
1882 }
1883 if (timeout < 0) {
1884 PyErr_SetString(PyExc_ValueError,
1885 "timeout must be positive or None");
1886 return NULL;
1887 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001888
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001889 seconds = (long)timeout;
1890 timeout = timeout - (double)seconds;
1891 timeoutspec.tv_sec = seconds;
1892 timeoutspec.tv_nsec = (long)(timeout * 1E9);
1893 ptimeoutspec = &timeoutspec;
1894 }
1895 else {
1896 PyErr_Format(PyExc_TypeError,
1897 "timeout argument must be an number "
1898 "or None, got %.200s",
1899 Py_TYPE(otimeout)->tp_name);
1900 return NULL;
1901 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001902
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001903 if (ch != NULL && ch != Py_None) {
1904 it = PyObject_GetIter(ch);
1905 if (it == NULL) {
1906 PyErr_SetString(PyExc_TypeError,
1907 "changelist is not iterable");
1908 return NULL;
1909 }
1910 nchanges = PyObject_Size(ch);
1911 if (nchanges < 0) {
1912 goto error;
1913 }
Georg Brandlc0e22b72010-03-14 10:51:01 +00001914
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001915 chl = PyMem_New(struct kevent, nchanges);
1916 if (chl == NULL) {
1917 PyErr_NoMemory();
1918 goto error;
1919 }
1920 i = 0;
1921 while ((ei = PyIter_Next(it)) != NULL) {
1922 if (!kqueue_event_Check(ei)) {
1923 Py_DECREF(ei);
1924 PyErr_SetString(PyExc_TypeError,
1925 "changelist must be an iterable of "
1926 "select.kevent objects");
1927 goto error;
1928 } else {
1929 chl[i++] = ((kqueue_event_Object *)ei)->e;
1930 }
1931 Py_DECREF(ei);
1932 }
1933 }
1934 Py_CLEAR(it);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001935
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001936 /* event list */
1937 if (nevents) {
1938 evl = PyMem_New(struct kevent, nevents);
1939 if (evl == NULL) {
1940 PyErr_NoMemory();
1941 goto error;
1942 }
1943 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001944
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001945 Py_BEGIN_ALLOW_THREADS
1946 gotevents = kevent(self->kqfd, chl, nchanges,
1947 evl, nevents, ptimeoutspec);
1948 Py_END_ALLOW_THREADS
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001949
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001950 if (gotevents == -1) {
1951 PyErr_SetFromErrno(PyExc_OSError);
1952 goto error;
1953 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001954
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001955 result = PyList_New(gotevents);
1956 if (result == NULL) {
1957 goto error;
1958 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001959
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001960 for (i = 0; i < gotevents; i++) {
1961 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001962
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001963 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1964 if (ch == NULL) {
1965 goto error;
1966 }
1967 ch->e = evl[i];
1968 PyList_SET_ITEM(result, i, (PyObject *)ch);
1969 }
1970 PyMem_Free(chl);
1971 PyMem_Free(evl);
1972 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001973
1974 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001975 PyMem_Free(chl);
1976 PyMem_Free(evl);
1977 Py_XDECREF(result);
1978 Py_XDECREF(it);
1979 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001980}
1981
1982PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00001983"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001984\n\
1985Calls the kernel kevent function.\n\
1986- changelist must be a list of kevent objects describing the changes\n\
1987 to be made to the kernel's watch list or None.\n\
1988- max_events lets you specify the maximum number of events that the\n\
1989 kernel will return.\n\
1990- timeout is the maximum time to wait in seconds, or else None,\n\
1991 to wait forever. timeout accepts floats for smaller timeouts, too.");
1992
1993
1994static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001995 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
1996 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
1997 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
1998 kqueue_queue_close_doc},
1999 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
2000 kqueue_queue_fileno_doc},
2001 {"control", (PyCFunction)kqueue_queue_control,
2002 METH_VARARGS , kqueue_queue_control_doc},
2003 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002004};
2005
2006static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002007 {"closed", (getter)kqueue_queue_get_closed, NULL,
2008 "True if the kqueue handler is closed"},
2009 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002010};
2011
2012PyDoc_STRVAR(kqueue_queue_doc,
2013"Kqueue syscall wrapper.\n\
2014\n\
2015For example, to start watching a socket for input:\n\
2016>>> kq = kqueue()\n\
2017>>> sock = socket()\n\
2018>>> sock.connect((host, port))\n\
2019>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
2020\n\
2021To wait one second for it to become writeable:\n\
2022>>> kq.control(None, 1, 1000)\n\
2023\n\
2024To stop listening:\n\
2025>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
2026
2027static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002028 PyVarObject_HEAD_INIT(NULL, 0)
2029 "select.kqueue", /* tp_name */
2030 sizeof(kqueue_queue_Object), /* tp_basicsize */
2031 0, /* tp_itemsize */
2032 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
2033 0, /* tp_print */
2034 0, /* tp_getattr */
2035 0, /* tp_setattr */
2036 0, /* tp_reserved */
2037 0, /* tp_repr */
2038 0, /* tp_as_number */
2039 0, /* tp_as_sequence */
2040 0, /* tp_as_mapping */
2041 0, /* tp_hash */
2042 0, /* tp_call */
2043 0, /* tp_str */
2044 0, /* tp_getattro */
2045 0, /* tp_setattro */
2046 0, /* tp_as_buffer */
2047 Py_TPFLAGS_DEFAULT, /* tp_flags */
2048 kqueue_queue_doc, /* tp_doc */
2049 0, /* tp_traverse */
2050 0, /* tp_clear */
2051 0, /* tp_richcompare */
2052 0, /* tp_weaklistoffset */
2053 0, /* tp_iter */
2054 0, /* tp_iternext */
2055 kqueue_queue_methods, /* tp_methods */
2056 0, /* tp_members */
2057 kqueue_queue_getsetlist, /* tp_getset */
2058 0, /* tp_base */
2059 0, /* tp_dict */
2060 0, /* tp_descr_get */
2061 0, /* tp_descr_set */
2062 0, /* tp_dictoffset */
2063 0, /* tp_init */
2064 0, /* tp_alloc */
2065 kqueue_queue_new, /* tp_new */
2066 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002067};
2068
2069#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002070
2071
2072
2073
2074
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002075/* ************************************************************************ */
2076
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002077PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002078"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
2079\n\
2080Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00002081The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002082rlist -- wait until ready for reading\n\
2083wlist -- wait until ready for writing\n\
2084xlist -- wait for an ``exceptional condition''\n\
2085If only one kind of condition is required, pass [] for the other lists.\n\
2086A file descriptor is either a socket or file object, or a small integer\n\
2087gotten from a fileno() method call on one of those.\n\
2088\n\
2089The optional 4th argument specifies a timeout in seconds; it may be\n\
2090a floating point number to specify fractions of seconds. If it is absent\n\
2091or None, the call will never time out.\n\
2092\n\
2093The return value is a tuple of three lists corresponding to the first three\n\
2094arguments; each contains the subset of the corresponding file descriptors\n\
2095that are ready.\n\
2096\n\
2097*** IMPORTANT NOTICE ***\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002098On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00002099descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002100
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002101static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002102 {"select", select_select, METH_VARARGS, select_doc},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002103#ifdef HAVE_POLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002104 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00002105#endif /* HAVE_POLL */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002106#ifdef HAVE_SYS_DEVPOLL_H
2107 {"devpoll", select_devpoll, METH_NOARGS, devpoll_doc},
2108#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002109 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002110};
2111
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002112PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002113"This module supports asynchronous I/O on multiple file descriptors.\n\
2114\n\
2115*** IMPORTANT NOTICE ***\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002116On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002117
Martin v. Löwis1a214512008-06-11 05:26:20 +00002118
2119static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002120 PyModuleDef_HEAD_INIT,
2121 "select",
2122 module_doc,
2123 -1,
2124 select_methods,
2125 NULL,
2126 NULL,
2127 NULL,
2128 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002129};
2130
Jesus Cead8b9ae62011-11-14 19:07:41 +01002131
2132
2133
Mark Hammond62b1ab12002-07-23 06:31:15 +00002134PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002135PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002136{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002137 PyObject *m;
2138 m = PyModule_Create(&selectmodule);
2139 if (m == NULL)
2140 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002141
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002142 Py_INCREF(PyExc_OSError);
2143 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002144
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002145#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002146#ifdef HAVE_BROKEN_PIPE_BUF
2147#undef PIPE_BUF
2148#define PIPE_BUF 512
2149#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002150 PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002151#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002152
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002153#if defined(HAVE_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002154#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002155 if (select_have_broken_poll()) {
2156 if (PyObject_DelAttrString(m, "poll") == -1) {
2157 PyErr_Clear();
2158 }
2159 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002160#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002161 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002162#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002163 if (PyType_Ready(&poll_Type) < 0)
2164 return NULL;
2165 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
2166 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
2167 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
2168 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
2169 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
2170 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002171
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002172#ifdef POLLRDNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002173 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002174#endif
2175#ifdef POLLRDBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002176 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002177#endif
2178#ifdef POLLWRNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002179 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002180#endif
2181#ifdef POLLWRBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002182 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002183#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002184#ifdef POLLMSG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002185 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002186#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002187 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002188#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002189
Jesus Cead8b9ae62011-11-14 19:07:41 +01002190#ifdef HAVE_SYS_DEVPOLL_H
2191 if (PyType_Ready(&devpoll_Type) < 0)
2192 return NULL;
2193#endif
2194
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002195#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002196 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
2197 if (PyType_Ready(&pyEpoll_Type) < 0)
2198 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002199
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002200 Py_INCREF(&pyEpoll_Type);
2201 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002202
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002203 PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
2204 PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
2205 PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
2206 PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
2207 PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
2208 PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002209#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002210 /* Kernel 2.6.2+ */
2211 PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002212#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002213 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
2214 PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
2215 PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
2216 PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
2217 PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
2218 PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002219
Benjamin Peterson95c16622011-12-27 15:36:32 -06002220#ifdef EPOLL_CLOEXEC
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002221 PyModule_AddIntConstant(m, "EPOLL_CLOEXEC", EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002222#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002223#endif /* HAVE_EPOLL */
2224
2225#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002226 kqueue_event_Type.tp_new = PyType_GenericNew;
2227 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
2228 if(PyType_Ready(&kqueue_event_Type) < 0)
2229 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002231 Py_INCREF(&kqueue_event_Type);
2232 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002233
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002234 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
2235 if(PyType_Ready(&kqueue_queue_Type) < 0)
2236 return NULL;
2237 Py_INCREF(&kqueue_queue_Type);
2238 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
2239
2240 /* event filters */
2241 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2242 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
2243 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
2244 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
2245 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002246#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002247 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002248#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002249 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
2250 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002251
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002252 /* event flags */
2253 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2254 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2255 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2256 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2257 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2258 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002260 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
2261 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002263 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2264 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002265
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002266 /* READ WRITE filter flag */
2267 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002268
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002269 /* VNODE filter flags */
2270 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2271 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2272 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2273 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2274 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2275 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2276 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002277
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002278 /* PROC filter flags */
2279 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2280 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2281 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2282 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2283 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002284
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002285 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2286 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2287 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
2288
2289 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002290#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002291 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2292 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2293 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002294#endif
2295
2296#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002297 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002298}