blob: 8964b675fcb3634d231642baa6254b577bbf7b71 [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;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000209 struct timeval tv, *tvp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000210 int imax, omax, emax, max;
211 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000212
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000213 /* convert arguments */
214 if (!PyArg_UnpackTuple(args, "select", 3, 4,
215 &ifdlist, &ofdlist, &efdlist, &tout))
216 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000217
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000218 if (tout == Py_None)
219 tvp = (struct timeval *)0;
220 else if (!PyNumber_Check(tout)) {
221 PyErr_SetString(PyExc_TypeError,
222 "timeout must be a float or None");
223 return NULL;
224 }
225 else {
Victor Stinnerb2a37732012-03-14 00:20:51 +0100226#ifdef MS_WINDOWS
227 time_t sec;
228 if (_PyTime_ObjectToTimeval(tout, &sec, &tv.tv_usec) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000229 return NULL;
Victor Stinnerb2a37732012-03-14 00:20:51 +0100230 assert(sizeof(tv.tv_sec) == sizeof(long));
231#if SIZEOF_TIME_T > SIZEOF_LONG
232 if (sec > LONG_MAX) {
233 PyErr_SetString(PyExc_OverflowError,
234 "timeout is too large");
235 return NULL;
236 }
237#endif
238 tv.tv_sec = (long)sec;
239#else
Brett Cannon8798ad32012-04-07 14:59:29 -0400240 /* 64-bit OS X has struct timeval.tv_usec as an int (and thus still 4
241 bytes as required), but no longer defined by a long. */
242 long tv_usec = tv.tv_usec;
243 if (_PyTime_ObjectToTimeval(tout, &tv.tv_sec, &tv_usec) == -1)
Victor Stinnerb2a37732012-03-14 00:20:51 +0100244 return NULL;
Brett Cannon8798ad32012-04-07 14:59:29 -0400245 tv.tv_usec = tv_usec;
Victor Stinnerb2a37732012-03-14 00:20:51 +0100246#endif
Victor Stinner5d272cc2012-03-13 13:35:55 +0100247 if (tv.tv_sec < 0) {
248 PyErr_SetString(PyExc_ValueError, "timeout must be non-negative");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000249 return NULL;
250 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000251 tvp = &tv;
252 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000253
Guido van Rossumed233a51992-06-23 09:07:03 +0000254
Barry Warsawb44740f2001-08-16 16:52:59 +0000255#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000256 /* Allocate memory for the lists */
257 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
258 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
259 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
260 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
261 if (rfd2obj) PyMem_DEL(rfd2obj);
262 if (wfd2obj) PyMem_DEL(wfd2obj);
263 if (efd2obj) PyMem_DEL(efd2obj);
264 return PyErr_NoMemory();
265 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000266#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000267 /* Convert sequences to fd_sets, and get maximum fd number
268 * propagates the Python exception set in seq2set()
269 */
270 rfd2obj[0].sentinel = -1;
271 wfd2obj[0].sentinel = -1;
272 efd2obj[0].sentinel = -1;
273 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
274 goto finally;
275 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
276 goto finally;
277 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
278 goto finally;
279 max = imax;
280 if (omax > max) max = omax;
281 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000282
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000283 Py_BEGIN_ALLOW_THREADS
284 n = select(max, &ifdset, &ofdset, &efdset, tvp);
285 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000286
Thomas Heller106f4c72002-09-24 16:51:00 +0000287#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 if (n == SOCKET_ERROR) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200289 PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000290 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000291#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000292 if (n < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200293 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000294 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000295#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000296 else {
297 /* any of these three calls can raise an exception. it's more
298 convenient to test for this after all three calls... but
299 is that acceptable?
300 */
301 ifdlist = set2list(&ifdset, rfd2obj);
302 ofdlist = set2list(&ofdset, wfd2obj);
303 efdlist = set2list(&efdset, efd2obj);
304 if (PyErr_Occurred())
305 ret = NULL;
306 else
307 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000308
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000309 Py_DECREF(ifdlist);
310 Py_DECREF(ofdlist);
311 Py_DECREF(efdlist);
312 }
313
Barry Warsawc1cb3601996-12-12 22:16:21 +0000314 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000315 reap_obj(rfd2obj);
316 reap_obj(wfd2obj);
317 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000318#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000319 PyMem_DEL(rfd2obj);
320 PyMem_DEL(wfd2obj);
321 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000322#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000324}
325
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000326#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000327/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000328 * poll() support
329 */
330
331typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000332 PyObject_HEAD
333 PyObject *dict;
334 int ufd_uptodate;
335 int ufd_len;
336 struct pollfd *ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000337} pollObject;
338
Jeremy Hylton938ace62002-07-17 16:30:39 +0000339static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000340
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000341/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000342 contained within a pollObject. Return 1 on success, 0 on an error.
343*/
344
345static int
346update_ufd_array(pollObject *self)
347{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000348 Py_ssize_t i, pos;
349 PyObject *key, *value;
350 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000352 self->ufd_len = PyDict_Size(self->dict);
353 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
354 if (self->ufds == NULL) {
355 self->ufds = old_ufds;
356 PyErr_NoMemory();
357 return 0;
358 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000359
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000360 i = pos = 0;
361 while (PyDict_Next(self->dict, &pos, &key, &value)) {
362 self->ufds[i].fd = PyLong_AsLong(key);
363 self->ufds[i].events = (short)PyLong_AsLong(value);
364 i++;
365 }
366 self->ufd_uptodate = 1;
367 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000368}
369
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000370PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000371"register(fd [, eventmask] ) -> None\n\n\
372Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000373fd -- either an integer, or an object with a fileno() method returning an\n\
374 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000375events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000376
377static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378poll_register(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000379{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000380 PyObject *o, *key, *value;
381 int fd, events = POLLIN | POLLPRI | POLLOUT;
382 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000384 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
385 return NULL;
386 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000388 fd = PyObject_AsFileDescriptor(o);
389 if (fd == -1) return NULL;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000391 /* Add entry to the internal dictionary: the key is the
392 file descriptor, and the value is the event mask. */
393 key = PyLong_FromLong(fd);
394 if (key == NULL)
395 return NULL;
396 value = PyLong_FromLong(events);
397 if (value == NULL) {
398 Py_DECREF(key);
399 return NULL;
400 }
401 err = PyDict_SetItem(self->dict, key, value);
402 Py_DECREF(key);
403 Py_DECREF(value);
404 if (err < 0)
405 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000406
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 self->ufd_uptodate = 0;
408
409 Py_INCREF(Py_None);
410 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000411}
412
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000413PyDoc_STRVAR(poll_modify_doc,
414"modify(fd, eventmask) -> None\n\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000415Modify an already registered file descriptor.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000416fd -- either an integer, or an object with a fileno() method returning an\n\
417 int.\n\
418events -- an optional bitmask describing the type of events to check for");
419
420static PyObject *
421poll_modify(pollObject *self, PyObject *args)
422{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000423 PyObject *o, *key, *value;
424 int fd, events;
425 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000426
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000427 if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) {
428 return NULL;
429 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000431 fd = PyObject_AsFileDescriptor(o);
432 if (fd == -1) return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000433
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000434 /* Modify registered fd */
435 key = PyLong_FromLong(fd);
436 if (key == NULL)
437 return NULL;
438 if (PyDict_GetItem(self->dict, key) == NULL) {
439 errno = ENOENT;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200440 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000441 return NULL;
442 }
443 value = PyLong_FromLong(events);
444 if (value == NULL) {
445 Py_DECREF(key);
446 return NULL;
447 }
448 err = PyDict_SetItem(self->dict, key, value);
449 Py_DECREF(key);
450 Py_DECREF(value);
451 if (err < 0)
452 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000453
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000454 self->ufd_uptodate = 0;
455
456 Py_INCREF(Py_None);
457 return Py_None;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000458}
459
460
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000461PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000462"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000463Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000464
465static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000466poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000467{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000468 PyObject *key;
469 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000470
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000471 fd = PyObject_AsFileDescriptor( o );
472 if (fd == -1)
473 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000474
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000475 /* Check whether the fd is already in the array */
476 key = PyLong_FromLong(fd);
477 if (key == NULL)
478 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 if (PyDict_DelItem(self->dict, key) == -1) {
481 Py_DECREF(key);
482 /* This will simply raise the KeyError set by PyDict_DelItem
483 if the file descriptor isn't registered. */
484 return NULL;
485 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000486
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000487 Py_DECREF(key);
488 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000489
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000490 Py_INCREF(Py_None);
491 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000492}
493
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000494PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000495"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
496Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000497any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000498
499static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000500poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000501{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000502 PyObject *result_list = NULL, *tout = NULL;
503 int timeout = 0, poll_result, i, j;
504 PyObject *value = NULL, *num = NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000505
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000506 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
507 return NULL;
508 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000509
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000510 /* Check values for timeout */
511 if (tout == NULL || tout == Py_None)
512 timeout = -1;
513 else if (!PyNumber_Check(tout)) {
514 PyErr_SetString(PyExc_TypeError,
515 "timeout must be an integer or None");
516 return NULL;
517 }
518 else {
519 tout = PyNumber_Long(tout);
520 if (!tout)
521 return NULL;
522 timeout = PyLong_AsLong(tout);
523 Py_DECREF(tout);
524 if (timeout == -1 && PyErr_Occurred())
525 return NULL;
526 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000527
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000528 /* Ensure the ufd array is up to date */
529 if (!self->ufd_uptodate)
530 if (update_ufd_array(self) == 0)
531 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000532
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000533 /* call poll() */
534 Py_BEGIN_ALLOW_THREADS
535 poll_result = poll(self->ufds, self->ufd_len, timeout);
536 Py_END_ALLOW_THREADS
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000537
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000538 if (poll_result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200539 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 return NULL;
541 }
542
543 /* build the result list */
544
545 result_list = PyList_New(poll_result);
546 if (!result_list)
547 return NULL;
548 else {
549 for (i = 0, j = 0; j < poll_result; j++) {
550 /* skip to the next fired descriptor */
551 while (!self->ufds[i].revents) {
552 i++;
553 }
554 /* if we hit a NULL return, set value to NULL
555 and break out of loop; code at end will
556 clean up result_list */
557 value = PyTuple_New(2);
558 if (value == NULL)
559 goto error;
560 num = PyLong_FromLong(self->ufds[i].fd);
561 if (num == NULL) {
562 Py_DECREF(value);
563 goto error;
564 }
565 PyTuple_SET_ITEM(value, 0, num);
566
567 /* The &0xffff is a workaround for AIX. 'revents'
568 is a 16-bit short, and IBM assigned POLLNVAL
569 to be 0x8000, so the conversion to int results
570 in a negative number. See SF bug #923315. */
571 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
572 if (num == NULL) {
573 Py_DECREF(value);
574 goto error;
575 }
576 PyTuple_SET_ITEM(value, 1, num);
577 if ((PyList_SetItem(result_list, j, value)) == -1) {
578 Py_DECREF(value);
579 goto error;
580 }
581 i++;
582 }
583 }
584 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000585
586 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000587 Py_DECREF(result_list);
588 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000589}
590
591static PyMethodDef poll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000592 {"register", (PyCFunction)poll_register,
593 METH_VARARGS, poll_register_doc},
594 {"modify", (PyCFunction)poll_modify,
595 METH_VARARGS, poll_modify_doc},
596 {"unregister", (PyCFunction)poll_unregister,
597 METH_O, poll_unregister_doc},
598 {"poll", (PyCFunction)poll_poll,
599 METH_VARARGS, poll_poll_doc},
600 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000601};
602
603static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000604newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000605{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000606 pollObject *self;
607 self = PyObject_New(pollObject, &poll_Type);
608 if (self == NULL)
609 return NULL;
610 /* ufd_uptodate is a Boolean, denoting whether the
611 array pointed to by ufds matches the contents of the dictionary. */
612 self->ufd_uptodate = 0;
613 self->ufds = NULL;
614 self->dict = PyDict_New();
615 if (self->dict == NULL) {
616 Py_DECREF(self);
617 return NULL;
618 }
619 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000620}
621
622static void
623poll_dealloc(pollObject *self)
624{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000625 if (self->ufds != NULL)
626 PyMem_DEL(self->ufds);
627 Py_XDECREF(self->dict);
628 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000629}
630
Tim Peters0c322792002-07-17 16:49:03 +0000631static PyTypeObject poll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000632 /* The ob_type field must be initialized in the module init function
633 * to be portable to Windows without using C++. */
634 PyVarObject_HEAD_INIT(NULL, 0)
635 "select.poll", /*tp_name*/
636 sizeof(pollObject), /*tp_basicsize*/
637 0, /*tp_itemsize*/
638 /* methods */
639 (destructor)poll_dealloc, /*tp_dealloc*/
640 0, /*tp_print*/
641 0, /*tp_getattr*/
642 0, /*tp_setattr*/
643 0, /*tp_reserved*/
644 0, /*tp_repr*/
645 0, /*tp_as_number*/
646 0, /*tp_as_sequence*/
647 0, /*tp_as_mapping*/
648 0, /*tp_hash*/
649 0, /*tp_call*/
650 0, /*tp_str*/
651 0, /*tp_getattro*/
652 0, /*tp_setattro*/
653 0, /*tp_as_buffer*/
654 Py_TPFLAGS_DEFAULT, /*tp_flags*/
655 0, /*tp_doc*/
656 0, /*tp_traverse*/
657 0, /*tp_clear*/
658 0, /*tp_richcompare*/
659 0, /*tp_weaklistoffset*/
660 0, /*tp_iter*/
661 0, /*tp_iternext*/
662 poll_methods, /*tp_methods*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000663};
664
Jesus Cead8b9ae62011-11-14 19:07:41 +0100665#ifdef HAVE_SYS_DEVPOLL_H
666typedef struct {
667 PyObject_HEAD
668 int fd_devpoll;
669 int max_n_fds;
670 int n_fds;
671 struct pollfd *fds;
672} devpollObject;
673
674static PyTypeObject devpoll_Type;
675
676static int devpoll_flush(devpollObject *self)
677{
678 int size, n;
679
680 if (!self->n_fds) return 0;
681
682 size = sizeof(struct pollfd)*self->n_fds;
683 self->n_fds = 0;
684
685 Py_BEGIN_ALLOW_THREADS
686 n = write(self->fd_devpoll, self->fds, size);
687 Py_END_ALLOW_THREADS
688
689 if (n == -1 ) {
690 PyErr_SetFromErrno(PyExc_IOError);
691 return -1;
692 }
693 if (n < size) {
694 /*
695 ** Data writed to /dev/poll is a binary data structure. It is not
696 ** clear what to do if a partial write occurred. For now, raise
697 ** an exception and see if we actually found this problem in
698 ** the wild.
699 ** See http://bugs.python.org/issue6397.
700 */
701 PyErr_Format(PyExc_IOError, "failed to write all pollfds. "
702 "Please, report at http://bugs.python.org/. "
703 "Data to report: Size tried: %d, actual size written: %d.",
704 size, n);
705 return -1;
706 }
707 return 0;
708}
709
710static PyObject *
711internal_devpoll_register(devpollObject *self, PyObject *args, int remove)
712{
713 PyObject *o;
714 int fd, events = POLLIN | POLLPRI | POLLOUT;
715
716 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
717 return NULL;
718 }
719
720 fd = PyObject_AsFileDescriptor(o);
721 if (fd == -1) return NULL;
722
723 if (remove) {
724 self->fds[self->n_fds].fd = fd;
725 self->fds[self->n_fds].events = POLLREMOVE;
726
727 if (++self->n_fds == self->max_n_fds) {
728 if (devpoll_flush(self))
729 return NULL;
730 }
731 }
732
733 self->fds[self->n_fds].fd = fd;
734 self->fds[self->n_fds].events = events;
735
736 if (++self->n_fds == self->max_n_fds) {
737 if (devpoll_flush(self))
738 return NULL;
739 }
740
741 Py_RETURN_NONE;
742}
743
744PyDoc_STRVAR(devpoll_register_doc,
745"register(fd [, eventmask] ) -> None\n\n\
746Register a file descriptor with the polling object.\n\
747fd -- either an integer, or an object with a fileno() method returning an\n\
748 int.\n\
749events -- an optional bitmask describing the type of events to check for");
750
751static PyObject *
752devpoll_register(devpollObject *self, PyObject *args)
753{
754 return internal_devpoll_register(self, args, 0);
755}
756
757PyDoc_STRVAR(devpoll_modify_doc,
758"modify(fd[, eventmask]) -> None\n\n\
759Modify a possible already registered file descriptor.\n\
760fd -- either an integer, or an object with a fileno() method returning an\n\
761 int.\n\
762events -- an optional bitmask describing the type of events to check for");
763
764static PyObject *
765devpoll_modify(devpollObject *self, PyObject *args)
766{
767 return internal_devpoll_register(self, args, 1);
768}
769
770
771PyDoc_STRVAR(devpoll_unregister_doc,
772"unregister(fd) -> None\n\n\
773Remove a file descriptor being tracked by the polling object.");
774
775static PyObject *
776devpoll_unregister(devpollObject *self, PyObject *o)
777{
778 int fd;
779
780 fd = PyObject_AsFileDescriptor( o );
781 if (fd == -1)
782 return NULL;
783
784 self->fds[self->n_fds].fd = fd;
785 self->fds[self->n_fds].events = POLLREMOVE;
786
787 if (++self->n_fds == self->max_n_fds) {
788 if (devpoll_flush(self))
789 return NULL;
790 }
791
792 Py_RETURN_NONE;
793}
794
795PyDoc_STRVAR(devpoll_poll_doc,
796"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
797Polls the set of registered file descriptors, returning a list containing \n\
798any descriptors that have events or errors to report.");
799
800static PyObject *
801devpoll_poll(devpollObject *self, PyObject *args)
802{
803 struct dvpoll dvp;
804 PyObject *result_list = NULL, *tout = NULL;
805 int poll_result, i;
806 long timeout;
807 PyObject *value, *num1, *num2;
808
809 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
810 return NULL;
811 }
812
813 /* Check values for timeout */
814 if (tout == NULL || tout == Py_None)
815 timeout = -1;
816 else if (!PyNumber_Check(tout)) {
817 PyErr_SetString(PyExc_TypeError,
818 "timeout must be an integer or None");
819 return NULL;
820 }
821 else {
822 tout = PyNumber_Long(tout);
823 if (!tout)
824 return NULL;
825 timeout = PyLong_AsLong(tout);
826 Py_DECREF(tout);
827 if (timeout == -1 && PyErr_Occurred())
828 return NULL;
829 }
830
831 if ((timeout < -1) || (timeout > INT_MAX)) {
832 PyErr_SetString(PyExc_OverflowError,
833 "timeout is out of range");
834 return NULL;
835 }
836
837 if (devpoll_flush(self))
838 return NULL;
839
840 dvp.dp_fds = self->fds;
841 dvp.dp_nfds = self->max_n_fds;
842 dvp.dp_timeout = timeout;
843
844 /* call devpoll() */
845 Py_BEGIN_ALLOW_THREADS
846 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
847 Py_END_ALLOW_THREADS
848
849 if (poll_result < 0) {
850 PyErr_SetFromErrno(PyExc_IOError);
851 return NULL;
852 }
853
854 /* build the result list */
855
856 result_list = PyList_New(poll_result);
857 if (!result_list)
858 return NULL;
859 else {
860 for (i = 0; i < poll_result; i++) {
861 num1 = PyLong_FromLong(self->fds[i].fd);
862 num2 = PyLong_FromLong(self->fds[i].revents);
863 if ((num1 == NULL) || (num2 == NULL)) {
864 Py_XDECREF(num1);
865 Py_XDECREF(num2);
866 goto error;
867 }
868 value = PyTuple_Pack(2, num1, num2);
869 Py_DECREF(num1);
870 Py_DECREF(num2);
871 if (value == NULL)
872 goto error;
873 if ((PyList_SetItem(result_list, i, value)) == -1) {
874 Py_DECREF(value);
875 goto error;
876 }
877 }
878 }
879
880 return result_list;
881
882 error:
883 Py_DECREF(result_list);
884 return NULL;
885}
886
887static PyMethodDef devpoll_methods[] = {
888 {"register", (PyCFunction)devpoll_register,
889 METH_VARARGS, devpoll_register_doc},
890 {"modify", (PyCFunction)devpoll_modify,
891 METH_VARARGS, devpoll_modify_doc},
892 {"unregister", (PyCFunction)devpoll_unregister,
893 METH_O, devpoll_unregister_doc},
894 {"poll", (PyCFunction)devpoll_poll,
895 METH_VARARGS, devpoll_poll_doc},
896 {NULL, NULL} /* sentinel */
897};
898
899static devpollObject *
900newDevPollObject(void)
901{
902 devpollObject *self;
903 int fd_devpoll, limit_result;
904 struct pollfd *fds;
905 struct rlimit limit;
906
907 Py_BEGIN_ALLOW_THREADS
908 /*
909 ** If we try to process more that getrlimit()
910 ** fds, the kernel will give an error, so
911 ** we set the limit here. It is a dynamic
912 ** value, because we can change rlimit() anytime.
913 */
914 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
915 if (limit_result != -1)
916 fd_devpoll = open("/dev/poll", O_RDWR);
917 Py_END_ALLOW_THREADS
918
919 if (limit_result == -1) {
920 PyErr_SetFromErrno(PyExc_OSError);
921 return NULL;
922 }
923 if (fd_devpoll == -1) {
924 PyErr_SetFromErrnoWithFilename(PyExc_IOError, "/dev/poll");
925 return NULL;
926 }
927
928 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
929 if (fds == NULL) {
930 close(fd_devpoll);
931 PyErr_NoMemory();
932 return NULL;
933 }
934
935 self = PyObject_New(devpollObject, &devpoll_Type);
936 if (self == NULL) {
937 close(fd_devpoll);
938 PyMem_DEL(fds);
939 return NULL;
940 }
941 self->fd_devpoll = fd_devpoll;
942 self->max_n_fds = limit.rlim_cur;
943 self->n_fds = 0;
944 self->fds = fds;
945
946 return self;
947}
948
949static void
950devpoll_dealloc(devpollObject *self)
951{
952 Py_BEGIN_ALLOW_THREADS
953 close(self->fd_devpoll);
954 Py_END_ALLOW_THREADS
955
956 PyMem_DEL(self->fds);
957
958 PyObject_Del(self);
959}
960
961static PyTypeObject devpoll_Type = {
962 /* The ob_type field must be initialized in the module init function
963 * to be portable to Windows without using C++. */
964 PyVarObject_HEAD_INIT(NULL, 0)
965 "select.devpoll", /*tp_name*/
966 sizeof(devpollObject), /*tp_basicsize*/
967 0, /*tp_itemsize*/
968 /* methods */
969 (destructor)devpoll_dealloc, /*tp_dealloc*/
970 0, /*tp_print*/
971 0, /*tp_getattr*/
972 0, /*tp_setattr*/
973 0, /*tp_reserved*/
974 0, /*tp_repr*/
975 0, /*tp_as_number*/
976 0, /*tp_as_sequence*/
977 0, /*tp_as_mapping*/
978 0, /*tp_hash*/
979 0, /*tp_call*/
980 0, /*tp_str*/
981 0, /*tp_getattro*/
982 0, /*tp_setattro*/
983 0, /*tp_as_buffer*/
984 Py_TPFLAGS_DEFAULT, /*tp_flags*/
985 0, /*tp_doc*/
986 0, /*tp_traverse*/
987 0, /*tp_clear*/
988 0, /*tp_richcompare*/
989 0, /*tp_weaklistoffset*/
990 0, /*tp_iter*/
991 0, /*tp_iternext*/
992 devpoll_methods, /*tp_methods*/
993};
994#endif /* HAVE_SYS_DEVPOLL_H */
995
996
997
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000998PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000999"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001000unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001001
1002static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001003select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001004{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001005 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001006}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001007
Jesus Cead8b9ae62011-11-14 19:07:41 +01001008#ifdef HAVE_SYS_DEVPOLL_H
1009PyDoc_STRVAR(devpoll_doc,
1010"Returns a polling object, which supports registering and\n\
1011unregistering file descriptors, and then polling them for I/O events.");
1012
1013static PyObject *
1014select_devpoll(PyObject *self, PyObject *unused)
1015{
1016 return (PyObject *)newDevPollObject();
1017}
1018#endif
1019
1020
Thomas Wouters477c8d52006-05-27 19:21:47 +00001021#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001022/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001023 * On some systems poll() sets errno on invalid file descriptors. We test
1024 * for this at runtime because this bug may be fixed or introduced between
1025 * OS releases.
1026 */
1027static int select_have_broken_poll(void)
1028{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001029 int poll_test;
1030 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001031
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001032 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001033
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001034 /* Create a file descriptor to make invalid */
1035 if (pipe(filedes) < 0) {
1036 return 1;
1037 }
1038 poll_struct.fd = filedes[0];
1039 close(filedes[0]);
1040 close(filedes[1]);
1041 poll_test = poll(&poll_struct, 1, 0);
1042 if (poll_test < 0) {
1043 return 1;
1044 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1045 return 1;
1046 }
1047 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001048}
1049#endif /* __APPLE__ */
1050
1051#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001052
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001053#ifdef HAVE_EPOLL
1054/* **************************************************************************
1055 * epoll interface for Linux 2.6
1056 *
1057 * Written by Christian Heimes
1058 * Inspired by Twisted's _epoll.pyx and select.poll()
1059 */
1060
1061#ifdef HAVE_SYS_EPOLL_H
1062#include <sys/epoll.h>
1063#endif
1064
1065typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001066 PyObject_HEAD
1067 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001068} pyEpoll_Object;
1069
1070static PyTypeObject pyEpoll_Type;
1071#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
1072
1073static PyObject *
1074pyepoll_err_closed(void)
1075{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001076 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
1077 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001078}
1079
1080static int
1081pyepoll_internal_close(pyEpoll_Object *self)
1082{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001083 int save_errno = 0;
1084 if (self->epfd >= 0) {
1085 int epfd = self->epfd;
1086 self->epfd = -1;
1087 Py_BEGIN_ALLOW_THREADS
1088 if (close(epfd) < 0)
1089 save_errno = errno;
1090 Py_END_ALLOW_THREADS
1091 }
1092 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001093}
1094
1095static PyObject *
Benjamin Peterson95c16622011-12-27 15:36:32 -06001096newPyEpoll_Object(PyTypeObject *type, int sizehint, int flags, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001097{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001098 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001099
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001100 assert(type != NULL && type->tp_alloc != NULL);
1101 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
1102 if (self == NULL)
1103 return NULL;
1104
1105 if (fd == -1) {
1106 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001107#ifdef HAVE_EPOLL_CREATE1
Benjamin Peterson83251c12011-12-27 16:01:21 -06001108 if (flags)
1109 self->epfd = epoll_create1(flags);
1110 else
Benjamin Peterson95c16622011-12-27 15:36:32 -06001111#endif
Benjamin Peterson83251c12011-12-27 16:01:21 -06001112 self->epfd = epoll_create(sizehint);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001113 Py_END_ALLOW_THREADS
1114 }
1115 else {
1116 self->epfd = fd;
1117 }
1118 if (self->epfd < 0) {
1119 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001120 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001121 return NULL;
1122 }
1123 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001124}
1125
1126
1127static PyObject *
1128pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1129{
Benjamin Peterson83251c12011-12-27 16:01:21 -06001130 int flags = 0, sizehint = FD_SETSIZE - 1;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001131 static char *kwlist[] = {"sizehint", "flags", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001132
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001133 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:epoll", kwlist,
1134 &sizehint, &flags))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001135 return NULL;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001136 if (sizehint < 0) {
1137 PyErr_SetString(PyExc_ValueError, "negative sizehint");
1138 return NULL;
1139 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001140
Benjamin Peterson95c16622011-12-27 15:36:32 -06001141 return newPyEpoll_Object(type, sizehint, flags, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001142}
1143
1144
1145static void
1146pyepoll_dealloc(pyEpoll_Object *self)
1147{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001148 (void)pyepoll_internal_close(self);
1149 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001150}
1151
1152static PyObject*
1153pyepoll_close(pyEpoll_Object *self)
1154{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001155 errno = pyepoll_internal_close(self);
1156 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001157 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001158 return NULL;
1159 }
1160 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001161}
1162
1163PyDoc_STRVAR(pyepoll_close_doc,
1164"close() -> None\n\
1165\n\
1166Close the epoll control file descriptor. Further operations on the epoll\n\
1167object will raise an exception.");
1168
1169static PyObject*
1170pyepoll_get_closed(pyEpoll_Object *self)
1171{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001172 if (self->epfd < 0)
1173 Py_RETURN_TRUE;
1174 else
1175 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001176}
1177
1178static PyObject*
1179pyepoll_fileno(pyEpoll_Object *self)
1180{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001181 if (self->epfd < 0)
1182 return pyepoll_err_closed();
1183 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001184}
1185
1186PyDoc_STRVAR(pyepoll_fileno_doc,
1187"fileno() -> int\n\
1188\n\
1189Return the epoll control file descriptor.");
1190
1191static PyObject*
1192pyepoll_fromfd(PyObject *cls, PyObject *args)
1193{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001194 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001195
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001196 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1197 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001198
Benjamin Peterson95c16622011-12-27 15:36:32 -06001199 return newPyEpoll_Object((PyTypeObject*)cls, FD_SETSIZE - 1, 0, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001200}
1201
1202PyDoc_STRVAR(pyepoll_fromfd_doc,
1203"fromfd(fd) -> epoll\n\
1204\n\
1205Create an epoll object from a given control fd.");
1206
1207static PyObject *
1208pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
1209{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001210 struct epoll_event ev;
1211 int result;
1212 int fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001213
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001214 if (epfd < 0)
1215 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001217 fd = PyObject_AsFileDescriptor(pfd);
1218 if (fd == -1) {
1219 return NULL;
1220 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001222 switch(op) {
1223 case EPOLL_CTL_ADD:
1224 case EPOLL_CTL_MOD:
1225 ev.events = events;
1226 ev.data.fd = fd;
1227 Py_BEGIN_ALLOW_THREADS
1228 result = epoll_ctl(epfd, op, fd, &ev);
1229 Py_END_ALLOW_THREADS
1230 break;
1231 case EPOLL_CTL_DEL:
1232 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1233 * operation required a non-NULL pointer in event, even
1234 * though this argument is ignored. */
1235 Py_BEGIN_ALLOW_THREADS
1236 result = epoll_ctl(epfd, op, fd, &ev);
1237 if (errno == EBADF) {
1238 /* fd already closed */
1239 result = 0;
1240 errno = 0;
1241 }
1242 Py_END_ALLOW_THREADS
1243 break;
1244 default:
1245 result = -1;
1246 errno = EINVAL;
1247 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001248
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001249 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001250 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001251 return NULL;
1252 }
1253 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001254}
1255
1256static PyObject *
1257pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1258{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001259 PyObject *pfd;
1260 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
1261 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001263 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
1264 &pfd, &events)) {
1265 return NULL;
1266 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001268 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001269}
1270
1271PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl222569d2010-08-02 20:47:56 +00001272"register(fd[, eventmask]) -> None\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001273\n\
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001274Registers a new fd or raises an OSError if the fd is already registered.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001275fd is the target file descriptor of the operation.\n\
1276events is a bit set composed of the various EPOLL constants; the default\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001277is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
1278\n\
1279The epoll interface supports all file descriptors that support poll.");
1280
1281static PyObject *
1282pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1283{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001284 PyObject *pfd;
1285 unsigned int events;
1286 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001287
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001288 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
1289 &pfd, &events)) {
1290 return NULL;
1291 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001292
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001293 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001294}
1295
1296PyDoc_STRVAR(pyepoll_modify_doc,
1297"modify(fd, eventmask) -> None\n\
1298\n\
1299fd is the target file descriptor of the operation\n\
1300events is a bit set composed of the various EPOLL constants");
1301
1302static PyObject *
1303pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1304{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001305 PyObject *pfd;
1306 static char *kwlist[] = {"fd", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
1309 &pfd)) {
1310 return NULL;
1311 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001312
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001313 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001314}
1315
1316PyDoc_STRVAR(pyepoll_unregister_doc,
1317"unregister(fd) -> None\n\
1318\n\
1319fd is the target file descriptor of the operation.");
1320
1321static PyObject *
1322pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1323{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001324 double dtimeout = -1.;
1325 int timeout;
1326 int maxevents = -1;
1327 int nfds, i;
1328 PyObject *elist = NULL, *etuple = NULL;
1329 struct epoll_event *evs = NULL;
1330 static char *kwlist[] = {"timeout", "maxevents", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001331
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001332 if (self->epfd < 0)
1333 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001335 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
1336 &dtimeout, &maxevents)) {
1337 return NULL;
1338 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 if (dtimeout < 0) {
1341 timeout = -1;
1342 }
1343 else if (dtimeout * 1000.0 > INT_MAX) {
1344 PyErr_SetString(PyExc_OverflowError,
1345 "timeout is too large");
1346 return NULL;
1347 }
1348 else {
1349 timeout = (int)(dtimeout * 1000.0);
1350 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001352 if (maxevents == -1) {
1353 maxevents = FD_SETSIZE-1;
1354 }
1355 else if (maxevents < 1) {
1356 PyErr_Format(PyExc_ValueError,
1357 "maxevents must be greater than 0, got %d",
1358 maxevents);
1359 return NULL;
1360 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001361
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001362 evs = PyMem_New(struct epoll_event, maxevents);
1363 if (evs == NULL) {
1364 Py_DECREF(self);
1365 PyErr_NoMemory();
1366 return NULL;
1367 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001368
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001369 Py_BEGIN_ALLOW_THREADS
1370 nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
1371 Py_END_ALLOW_THREADS
1372 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001373 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001374 goto error;
1375 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001376
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001377 elist = PyList_New(nfds);
1378 if (elist == NULL) {
1379 goto error;
1380 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001382 for (i = 0; i < nfds; i++) {
1383 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
1384 if (etuple == NULL) {
1385 Py_CLEAR(elist);
1386 goto error;
1387 }
1388 PyList_SET_ITEM(elist, i, etuple);
1389 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001390
Christian Heimesf6cd9672008-03-26 13:45:42 +00001391 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001392 PyMem_Free(evs);
1393 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001394}
1395
1396PyDoc_STRVAR(pyepoll_poll_doc,
1397"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1398\n\
1399Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1400in seconds (as float). -1 makes poll wait indefinitely.\n\
1401Up to maxevents are returned to the caller.");
1402
1403static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001404 {"fromfd", (PyCFunction)pyepoll_fromfd,
1405 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1406 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1407 pyepoll_close_doc},
1408 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1409 pyepoll_fileno_doc},
1410 {"modify", (PyCFunction)pyepoll_modify,
1411 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1412 {"register", (PyCFunction)pyepoll_register,
1413 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1414 {"unregister", (PyCFunction)pyepoll_unregister,
1415 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1416 {"poll", (PyCFunction)pyepoll_poll,
1417 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
1418 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001419};
1420
1421static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001422 {"closed", (getter)pyepoll_get_closed, NULL,
1423 "True if the epoll handler is closed"},
1424 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001425};
1426
1427PyDoc_STRVAR(pyepoll_doc,
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001428"select.epoll(sizehint=-1, flags=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001429\n\
1430Returns an epolling object\n\
1431\n\
1432sizehint must be a positive integer or -1 for the default size. The\n\
1433sizehint is used to optimize internal data structures. It doesn't limit\n\
1434the maximum number of monitored events.");
1435
1436static PyTypeObject pyEpoll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001437 PyVarObject_HEAD_INIT(NULL, 0)
1438 "select.epoll", /* tp_name */
1439 sizeof(pyEpoll_Object), /* tp_basicsize */
1440 0, /* tp_itemsize */
1441 (destructor)pyepoll_dealloc, /* tp_dealloc */
1442 0, /* tp_print */
1443 0, /* tp_getattr */
1444 0, /* tp_setattr */
1445 0, /* tp_reserved */
1446 0, /* tp_repr */
1447 0, /* tp_as_number */
1448 0, /* tp_as_sequence */
1449 0, /* tp_as_mapping */
1450 0, /* tp_hash */
1451 0, /* tp_call */
1452 0, /* tp_str */
1453 PyObject_GenericGetAttr, /* tp_getattro */
1454 0, /* tp_setattro */
1455 0, /* tp_as_buffer */
1456 Py_TPFLAGS_DEFAULT, /* tp_flags */
1457 pyepoll_doc, /* tp_doc */
1458 0, /* tp_traverse */
1459 0, /* tp_clear */
1460 0, /* tp_richcompare */
1461 0, /* tp_weaklistoffset */
1462 0, /* tp_iter */
1463 0, /* tp_iternext */
1464 pyepoll_methods, /* tp_methods */
1465 0, /* tp_members */
1466 pyepoll_getsetlist, /* tp_getset */
1467 0, /* tp_base */
1468 0, /* tp_dict */
1469 0, /* tp_descr_get */
1470 0, /* tp_descr_set */
1471 0, /* tp_dictoffset */
1472 0, /* tp_init */
1473 0, /* tp_alloc */
1474 pyepoll_new, /* tp_new */
1475 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001476};
1477
1478#endif /* HAVE_EPOLL */
1479
1480#ifdef HAVE_KQUEUE
1481/* **************************************************************************
1482 * kqueue interface for BSD
1483 *
1484 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1485 * All rights reserved.
1486 *
1487 * Redistribution and use in source and binary forms, with or without
1488 * modification, are permitted provided that the following conditions
1489 * are met:
1490 * 1. Redistributions of source code must retain the above copyright
1491 * notice, this list of conditions and the following disclaimer.
1492 * 2. Redistributions in binary form must reproduce the above copyright
1493 * notice, this list of conditions and the following disclaimer in the
1494 * documentation and/or other materials provided with the distribution.
1495 *
1496 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1497 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1498 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1499 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1500 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1501 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1502 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1503 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1504 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1505 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1506 * SUCH DAMAGE.
1507 */
1508
1509#ifdef HAVE_SYS_EVENT_H
1510#include <sys/event.h>
1511#endif
1512
1513PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001514"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001515\n\
1516This object is the equivalent of the struct kevent for the C API.\n\
1517\n\
1518See the kqueue manpage for more detailed information about the meaning\n\
1519of the arguments.\n\
1520\n\
1521One minor note: while you might hope that udata could store a\n\
1522reference to a python object, it cannot, because it is impossible to\n\
1523keep a proper reference count of the object once it's passed into the\n\
1524kernel. Therefore, I have restricted it to only storing an integer. I\n\
1525recommend ignoring it and simply using the 'ident' field to key off\n\
1526of. You could also set up a dictionary on the python side to store a\n\
1527udata->object mapping.");
1528
1529typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001530 PyObject_HEAD
1531 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001532} kqueue_event_Object;
1533
1534static PyTypeObject kqueue_event_Type;
1535
1536#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1537
1538typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001539 PyObject_HEAD
1540 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001541} kqueue_queue_Object;
1542
1543static PyTypeObject kqueue_queue_Type;
1544
1545#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1546
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001547#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1548# error uintptr_t does not match void *!
1549#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1550# define T_UINTPTRT T_ULONGLONG
1551# define T_INTPTRT T_LONGLONG
1552# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1553# define UINTPTRT_FMT_UNIT "K"
1554# define INTPTRT_FMT_UNIT "L"
1555#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1556# define T_UINTPTRT T_ULONG
1557# define T_INTPTRT T_LONG
1558# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1559# define UINTPTRT_FMT_UNIT "k"
1560# define INTPTRT_FMT_UNIT "l"
1561#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1562# define T_UINTPTRT T_UINT
1563# define T_INTPTRT T_INT
1564# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1565# define UINTPTRT_FMT_UNIT "I"
1566# define INTPTRT_FMT_UNIT "i"
1567#else
1568# error uintptr_t does not match int, long, or long long!
1569#endif
1570
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001571/* Unfortunately, we can't store python objects in udata, because
1572 * kevents in the kernel can be removed without warning, which would
1573 * forever lose the refcount on the object stored with it.
1574 */
1575
1576#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1577static struct PyMemberDef kqueue_event_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001578 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1579 {"filter", T_SHORT, KQ_OFF(e.filter)},
1580 {"flags", T_USHORT, KQ_OFF(e.flags)},
1581 {"fflags", T_UINT, KQ_OFF(e.fflags)},
1582 {"data", T_INTPTRT, KQ_OFF(e.data)},
1583 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1584 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001585};
1586#undef KQ_OFF
1587
1588static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001589
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001590kqueue_event_repr(kqueue_event_Object *s)
1591{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001592 char buf[1024];
1593 PyOS_snprintf(
1594 buf, sizeof(buf),
1595 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1596 "data=0x%zd udata=%p>",
1597 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1598 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1599 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001600}
1601
1602static int
1603kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1604{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001605 PyObject *pfd;
1606 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1607 "data", "udata", NULL};
1608 static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001609
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001610 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001611
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001612 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1613 &pfd, &(self->e.filter), &(self->e.flags),
1614 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1615 return -1;
1616 }
1617
1618 if (PyLong_Check(pfd)) {
1619 self->e.ident = PyLong_AsUintptr_t(pfd);
1620 }
1621 else {
1622 self->e.ident = PyObject_AsFileDescriptor(pfd);
1623 }
1624 if (PyErr_Occurred()) {
1625 return -1;
1626 }
1627 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001628}
1629
1630static PyObject *
1631kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001632 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001633{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001634 Py_intptr_t result = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001635
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001636 if (!kqueue_event_Check(o)) {
1637 if (op == Py_EQ || op == Py_NE) {
1638 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1639 Py_INCREF(res);
1640 return res;
1641 }
1642 PyErr_Format(PyExc_TypeError,
1643 "can't compare %.200s to %.200s",
1644 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1645 return NULL;
1646 }
1647 if (((result = s->e.ident - o->e.ident) == 0) &&
1648 ((result = s->e.filter - o->e.filter) == 0) &&
1649 ((result = s->e.flags - o->e.flags) == 0) &&
1650 ((result = s->e.fflags - o->e.fflags) == 0) &&
1651 ((result = s->e.data - o->e.data) == 0) &&
1652 ((result = s->e.udata - o->e.udata) == 0)
1653 ) {
1654 result = 0;
1655 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001656
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001657 switch (op) {
1658 case Py_EQ:
1659 result = (result == 0);
1660 break;
1661 case Py_NE:
1662 result = (result != 0);
1663 break;
1664 case Py_LE:
1665 result = (result <= 0);
1666 break;
1667 case Py_GE:
1668 result = (result >= 0);
1669 break;
1670 case Py_LT:
1671 result = (result < 0);
1672 break;
1673 case Py_GT:
1674 result = (result > 0);
1675 break;
1676 }
1677 return PyBool_FromLong((long)result);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001678}
1679
1680static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001681 PyVarObject_HEAD_INIT(NULL, 0)
1682 "select.kevent", /* tp_name */
1683 sizeof(kqueue_event_Object), /* tp_basicsize */
1684 0, /* tp_itemsize */
1685 0, /* tp_dealloc */
1686 0, /* tp_print */
1687 0, /* tp_getattr */
1688 0, /* tp_setattr */
1689 0, /* tp_reserved */
1690 (reprfunc)kqueue_event_repr, /* tp_repr */
1691 0, /* tp_as_number */
1692 0, /* tp_as_sequence */
1693 0, /* tp_as_mapping */
1694 0, /* tp_hash */
1695 0, /* tp_call */
1696 0, /* tp_str */
1697 0, /* tp_getattro */
1698 0, /* tp_setattro */
1699 0, /* tp_as_buffer */
1700 Py_TPFLAGS_DEFAULT, /* tp_flags */
1701 kqueue_event_doc, /* tp_doc */
1702 0, /* tp_traverse */
1703 0, /* tp_clear */
1704 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1705 0, /* tp_weaklistoffset */
1706 0, /* tp_iter */
1707 0, /* tp_iternext */
1708 0, /* tp_methods */
1709 kqueue_event_members, /* tp_members */
1710 0, /* tp_getset */
1711 0, /* tp_base */
1712 0, /* tp_dict */
1713 0, /* tp_descr_get */
1714 0, /* tp_descr_set */
1715 0, /* tp_dictoffset */
1716 (initproc)kqueue_event_init, /* tp_init */
1717 0, /* tp_alloc */
1718 0, /* tp_new */
1719 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001720};
1721
1722static PyObject *
1723kqueue_queue_err_closed(void)
1724{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001725 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1726 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001727}
1728
1729static int
1730kqueue_queue_internal_close(kqueue_queue_Object *self)
1731{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001732 int save_errno = 0;
1733 if (self->kqfd >= 0) {
1734 int kqfd = self->kqfd;
1735 self->kqfd = -1;
1736 Py_BEGIN_ALLOW_THREADS
1737 if (close(kqfd) < 0)
1738 save_errno = errno;
1739 Py_END_ALLOW_THREADS
1740 }
1741 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001742}
1743
1744static PyObject *
1745newKqueue_Object(PyTypeObject *type, SOCKET fd)
1746{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001747 kqueue_queue_Object *self;
1748 assert(type != NULL && type->tp_alloc != NULL);
1749 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1750 if (self == NULL) {
1751 return NULL;
1752 }
1753
1754 if (fd == -1) {
1755 Py_BEGIN_ALLOW_THREADS
1756 self->kqfd = kqueue();
1757 Py_END_ALLOW_THREADS
1758 }
1759 else {
1760 self->kqfd = fd;
1761 }
1762 if (self->kqfd < 0) {
1763 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001764 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001765 return NULL;
1766 }
1767 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001768}
1769
1770static PyObject *
1771kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1772{
1773
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001774 if ((args != NULL && PyObject_Size(args)) ||
1775 (kwds != NULL && PyObject_Size(kwds))) {
1776 PyErr_SetString(PyExc_ValueError,
1777 "select.kqueue doesn't accept arguments");
1778 return NULL;
1779 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001780
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001781 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001782}
1783
1784static void
1785kqueue_queue_dealloc(kqueue_queue_Object *self)
1786{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001787 kqueue_queue_internal_close(self);
1788 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001789}
1790
1791static PyObject*
1792kqueue_queue_close(kqueue_queue_Object *self)
1793{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001794 errno = kqueue_queue_internal_close(self);
1795 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001796 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001797 return NULL;
1798 }
1799 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001800}
1801
1802PyDoc_STRVAR(kqueue_queue_close_doc,
1803"close() -> None\n\
1804\n\
1805Close the kqueue control file descriptor. Further operations on the kqueue\n\
1806object will raise an exception.");
1807
1808static PyObject*
1809kqueue_queue_get_closed(kqueue_queue_Object *self)
1810{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001811 if (self->kqfd < 0)
1812 Py_RETURN_TRUE;
1813 else
1814 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001815}
1816
1817static PyObject*
1818kqueue_queue_fileno(kqueue_queue_Object *self)
1819{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001820 if (self->kqfd < 0)
1821 return kqueue_queue_err_closed();
1822 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001823}
1824
1825PyDoc_STRVAR(kqueue_queue_fileno_doc,
1826"fileno() -> int\n\
1827\n\
1828Return the kqueue control file descriptor.");
1829
1830static PyObject*
1831kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1832{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001833 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001834
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001835 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1836 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001837
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001838 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001839}
1840
1841PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1842"fromfd(fd) -> kqueue\n\
1843\n\
1844Create a kqueue object from a given control fd.");
1845
1846static PyObject *
1847kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1848{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001849 int nevents = 0;
1850 int gotevents = 0;
1851 int nchanges = 0;
1852 int i = 0;
1853 PyObject *otimeout = NULL;
1854 PyObject *ch = NULL;
1855 PyObject *it = NULL, *ei = NULL;
1856 PyObject *result = NULL;
1857 struct kevent *evl = NULL;
1858 struct kevent *chl = NULL;
Victor Stinnerd327f9d2012-03-13 15:29:08 +01001859 struct timespec timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001860 struct timespec *ptimeoutspec;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001862 if (self->kqfd < 0)
1863 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001865 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1866 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001868 if (nevents < 0) {
1869 PyErr_Format(PyExc_ValueError,
1870 "Length of eventlist must be 0 or positive, got %d",
1871 nevents);
1872 return NULL;
1873 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001874
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001875 if (otimeout == Py_None || otimeout == NULL) {
1876 ptimeoutspec = NULL;
1877 }
1878 else if (PyNumber_Check(otimeout)) {
Victor Stinner5d272cc2012-03-13 13:35:55 +01001879 if (_PyTime_ObjectToTimespec(otimeout,
1880 &timeout.tv_sec, &timeout.tv_nsec) == -1)
1881 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001882
Victor Stinner5d272cc2012-03-13 13:35:55 +01001883 if (timeout.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001884 PyErr_SetString(PyExc_ValueError,
1885 "timeout must be positive or None");
1886 return NULL;
1887 }
Victor Stinnerd528b012012-03-13 16:25:35 +01001888 ptimeoutspec = &timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001889 }
1890 else {
1891 PyErr_Format(PyExc_TypeError,
1892 "timeout argument must be an number "
1893 "or None, got %.200s",
1894 Py_TYPE(otimeout)->tp_name);
1895 return NULL;
1896 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001897
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001898 if (ch != NULL && ch != Py_None) {
1899 it = PyObject_GetIter(ch);
1900 if (it == NULL) {
1901 PyErr_SetString(PyExc_TypeError,
1902 "changelist is not iterable");
1903 return NULL;
1904 }
1905 nchanges = PyObject_Size(ch);
1906 if (nchanges < 0) {
1907 goto error;
1908 }
Georg Brandlc0e22b72010-03-14 10:51:01 +00001909
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001910 chl = PyMem_New(struct kevent, nchanges);
1911 if (chl == NULL) {
1912 PyErr_NoMemory();
1913 goto error;
1914 }
1915 i = 0;
1916 while ((ei = PyIter_Next(it)) != NULL) {
1917 if (!kqueue_event_Check(ei)) {
1918 Py_DECREF(ei);
1919 PyErr_SetString(PyExc_TypeError,
1920 "changelist must be an iterable of "
1921 "select.kevent objects");
1922 goto error;
1923 } else {
1924 chl[i++] = ((kqueue_event_Object *)ei)->e;
1925 }
1926 Py_DECREF(ei);
1927 }
1928 }
1929 Py_CLEAR(it);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001930
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001931 /* event list */
1932 if (nevents) {
1933 evl = PyMem_New(struct kevent, nevents);
1934 if (evl == NULL) {
1935 PyErr_NoMemory();
1936 goto error;
1937 }
1938 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001939
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001940 Py_BEGIN_ALLOW_THREADS
1941 gotevents = kevent(self->kqfd, chl, nchanges,
1942 evl, nevents, ptimeoutspec);
1943 Py_END_ALLOW_THREADS
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001944
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001945 if (gotevents == -1) {
1946 PyErr_SetFromErrno(PyExc_OSError);
1947 goto error;
1948 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001949
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001950 result = PyList_New(gotevents);
1951 if (result == NULL) {
1952 goto error;
1953 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001954
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001955 for (i = 0; i < gotevents; i++) {
1956 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001957
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001958 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1959 if (ch == NULL) {
1960 goto error;
1961 }
1962 ch->e = evl[i];
1963 PyList_SET_ITEM(result, i, (PyObject *)ch);
1964 }
1965 PyMem_Free(chl);
1966 PyMem_Free(evl);
1967 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001968
1969 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001970 PyMem_Free(chl);
1971 PyMem_Free(evl);
1972 Py_XDECREF(result);
1973 Py_XDECREF(it);
1974 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001975}
1976
1977PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00001978"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001979\n\
1980Calls the kernel kevent function.\n\
1981- changelist must be a list of kevent objects describing the changes\n\
1982 to be made to the kernel's watch list or None.\n\
1983- max_events lets you specify the maximum number of events that the\n\
1984 kernel will return.\n\
1985- timeout is the maximum time to wait in seconds, or else None,\n\
1986 to wait forever. timeout accepts floats for smaller timeouts, too.");
1987
1988
1989static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001990 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
1991 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
1992 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
1993 kqueue_queue_close_doc},
1994 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
1995 kqueue_queue_fileno_doc},
1996 {"control", (PyCFunction)kqueue_queue_control,
1997 METH_VARARGS , kqueue_queue_control_doc},
1998 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001999};
2000
2001static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002002 {"closed", (getter)kqueue_queue_get_closed, NULL,
2003 "True if the kqueue handler is closed"},
2004 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002005};
2006
2007PyDoc_STRVAR(kqueue_queue_doc,
2008"Kqueue syscall wrapper.\n\
2009\n\
2010For example, to start watching a socket for input:\n\
2011>>> kq = kqueue()\n\
2012>>> sock = socket()\n\
2013>>> sock.connect((host, port))\n\
2014>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
2015\n\
2016To wait one second for it to become writeable:\n\
2017>>> kq.control(None, 1, 1000)\n\
2018\n\
2019To stop listening:\n\
2020>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
2021
2022static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002023 PyVarObject_HEAD_INIT(NULL, 0)
2024 "select.kqueue", /* tp_name */
2025 sizeof(kqueue_queue_Object), /* tp_basicsize */
2026 0, /* tp_itemsize */
2027 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
2028 0, /* tp_print */
2029 0, /* tp_getattr */
2030 0, /* tp_setattr */
2031 0, /* tp_reserved */
2032 0, /* tp_repr */
2033 0, /* tp_as_number */
2034 0, /* tp_as_sequence */
2035 0, /* tp_as_mapping */
2036 0, /* tp_hash */
2037 0, /* tp_call */
2038 0, /* tp_str */
2039 0, /* tp_getattro */
2040 0, /* tp_setattro */
2041 0, /* tp_as_buffer */
2042 Py_TPFLAGS_DEFAULT, /* tp_flags */
2043 kqueue_queue_doc, /* tp_doc */
2044 0, /* tp_traverse */
2045 0, /* tp_clear */
2046 0, /* tp_richcompare */
2047 0, /* tp_weaklistoffset */
2048 0, /* tp_iter */
2049 0, /* tp_iternext */
2050 kqueue_queue_methods, /* tp_methods */
2051 0, /* tp_members */
2052 kqueue_queue_getsetlist, /* tp_getset */
2053 0, /* tp_base */
2054 0, /* tp_dict */
2055 0, /* tp_descr_get */
2056 0, /* tp_descr_set */
2057 0, /* tp_dictoffset */
2058 0, /* tp_init */
2059 0, /* tp_alloc */
2060 kqueue_queue_new, /* tp_new */
2061 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002062};
2063
2064#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002065
2066
2067
2068
2069
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002070/* ************************************************************************ */
2071
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002072PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002073"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
2074\n\
2075Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00002076The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002077rlist -- wait until ready for reading\n\
2078wlist -- wait until ready for writing\n\
2079xlist -- wait for an ``exceptional condition''\n\
2080If only one kind of condition is required, pass [] for the other lists.\n\
2081A file descriptor is either a socket or file object, or a small integer\n\
2082gotten from a fileno() method call on one of those.\n\
2083\n\
2084The optional 4th argument specifies a timeout in seconds; it may be\n\
2085a floating point number to specify fractions of seconds. If it is absent\n\
2086or None, the call will never time out.\n\
2087\n\
2088The return value is a tuple of three lists corresponding to the first three\n\
2089arguments; each contains the subset of the corresponding file descriptors\n\
2090that are ready.\n\
2091\n\
2092*** IMPORTANT NOTICE ***\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002093On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00002094descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002095
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002096static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002097 {"select", select_select, METH_VARARGS, select_doc},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002098#ifdef HAVE_POLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002099 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00002100#endif /* HAVE_POLL */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002101#ifdef HAVE_SYS_DEVPOLL_H
2102 {"devpoll", select_devpoll, METH_NOARGS, devpoll_doc},
2103#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002104 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002105};
2106
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002107PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002108"This module supports asynchronous I/O on multiple file descriptors.\n\
2109\n\
2110*** IMPORTANT NOTICE ***\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002111On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002112
Martin v. Löwis1a214512008-06-11 05:26:20 +00002113
2114static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002115 PyModuleDef_HEAD_INIT,
2116 "select",
2117 module_doc,
2118 -1,
2119 select_methods,
2120 NULL,
2121 NULL,
2122 NULL,
2123 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002124};
2125
Jesus Cead8b9ae62011-11-14 19:07:41 +01002126
2127
2128
Mark Hammond62b1ab12002-07-23 06:31:15 +00002129PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002130PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002131{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002132 PyObject *m;
2133 m = PyModule_Create(&selectmodule);
2134 if (m == NULL)
2135 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002136
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002137 Py_INCREF(PyExc_OSError);
2138 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002139
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002140#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002141#ifdef HAVE_BROKEN_PIPE_BUF
2142#undef PIPE_BUF
2143#define PIPE_BUF 512
2144#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002145 PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002146#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002147
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002148#if defined(HAVE_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002149#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002150 if (select_have_broken_poll()) {
2151 if (PyObject_DelAttrString(m, "poll") == -1) {
2152 PyErr_Clear();
2153 }
2154 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002155#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002156 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002157#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002158 if (PyType_Ready(&poll_Type) < 0)
2159 return NULL;
2160 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
2161 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
2162 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
2163 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
2164 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
2165 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002166
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002167#ifdef POLLRDNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002168 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002169#endif
2170#ifdef POLLRDBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002171 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002172#endif
2173#ifdef POLLWRNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002174 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002175#endif
2176#ifdef POLLWRBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002177 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002178#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002179#ifdef POLLMSG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002180 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002181#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002182 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002183#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002184
Jesus Cead8b9ae62011-11-14 19:07:41 +01002185#ifdef HAVE_SYS_DEVPOLL_H
2186 if (PyType_Ready(&devpoll_Type) < 0)
2187 return NULL;
2188#endif
2189
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002190#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002191 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
2192 if (PyType_Ready(&pyEpoll_Type) < 0)
2193 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002194
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002195 Py_INCREF(&pyEpoll_Type);
2196 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002197
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002198 PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
2199 PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
2200 PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
2201 PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
2202 PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
2203 PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002204#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002205 /* Kernel 2.6.2+ */
2206 PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002207#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002208 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
2209 PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
2210 PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
2211 PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
2212 PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
2213 PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002214
Benjamin Peterson95c16622011-12-27 15:36:32 -06002215#ifdef EPOLL_CLOEXEC
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002216 PyModule_AddIntConstant(m, "EPOLL_CLOEXEC", EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002217#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002218#endif /* HAVE_EPOLL */
2219
2220#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002221 kqueue_event_Type.tp_new = PyType_GenericNew;
2222 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
2223 if(PyType_Ready(&kqueue_event_Type) < 0)
2224 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002226 Py_INCREF(&kqueue_event_Type);
2227 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002228
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002229 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
2230 if(PyType_Ready(&kqueue_queue_Type) < 0)
2231 return NULL;
2232 Py_INCREF(&kqueue_queue_Type);
2233 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
2234
2235 /* event filters */
2236 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2237 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
2238 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
2239 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
2240 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002241#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002242 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002243#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002244 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
2245 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002247 /* event flags */
2248 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2249 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2250 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2251 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2252 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2253 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002254
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002255 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
2256 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002257
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002258 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2259 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002261 /* READ WRITE filter flag */
2262 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002264 /* VNODE filter flags */
2265 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2266 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2267 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2268 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2269 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2270 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2271 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002273 /* PROC filter flags */
2274 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2275 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2276 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2277 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2278 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002279
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002280 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2281 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2282 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
2283
2284 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002285#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002286 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2287 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2288 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002289#endif
2290
2291#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002292 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002293}