blob: 20f23d92603870da51a9fabd571470f98c042d95 [file] [log] [blame]
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00001/* select - Module containing unix select(2) call.
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002 Under Unix, the file descriptors are small integers.
3 Under Win32, select only exists for sockets, and sockets may
4 have any value except INVALID_SOCKET.
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00005*/
Guido van Rossumed233a51992-06-23 09:07:03 +00006
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00007#include "Python.h"
Christian Heimes4fbc72b2008-03-22 00:47:35 +00008#include <structmember.h>
Guido van Rossumed233a51992-06-23 09:07:03 +00009
Thomas Wouters477c8d52006-05-27 19:21:47 +000010#ifdef __APPLE__
11 /* Perform runtime testing for a broken poll on OSX to make it easier
12 * to use the same binary on multiple releases of the OS.
13 */
14#undef HAVE_BROKEN_POLL
15#endif
16
Tim Petersd92dfe02000-12-12 01:18:41 +000017/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
18 64 is too small (too many people have bumped into that limit).
19 Here we boost it.
20 Users who want even more than the boosted limit should #define
21 FD_SETSIZE higher before this; e.g., via compiler /D switch.
22*/
23#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
24#define FD_SETSIZE 512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000025#endif
Tim Petersd92dfe02000-12-12 01:18:41 +000026
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000027#if defined(HAVE_POLL_H)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000028#include <poll.h>
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000029#elif defined(HAVE_SYS_POLL_H)
30#include <sys/poll.h>
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000031#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000032
Guido van Rossum37273171996-12-09 18:47:43 +000033#ifdef __sgi
34/* This is missing from unistd.h */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000035extern void bzero(void *, int);
Guido van Rossum37273171996-12-09 18:47:43 +000036#endif
37
Thomas Wouters0e3f5912006-08-11 14:57:12 +000038#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000039#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000040#endif
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000041
Andrew MacIntyre7bf68332002-03-03 02:59:16 +000042#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000043#include <sys/time.h>
44#include <utils.h>
45#endif
46
Guido van Rossum6f489d91996-06-28 20:15:15 +000047#ifdef MS_WINDOWS
Christian Heimesc36625b2008-01-04 13:33:00 +000048# define WIN32_LEAN_AND_MEAN
Thomas Wouters0e3f5912006-08-11 14:57:12 +000049# include <winsock.h>
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000050#else
Thomas Wouters0e3f5912006-08-11 14:57:12 +000051# define SOCKET int
Skip Montanaroeb33e5a2007-08-17 12:57:41 +000052# if defined(__VMS)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000053# include <socket.h>
54# endif
Guido van Rossumbcc20741998-08-04 22:53:56 +000055#endif
Guido van Rossumed233a51992-06-23 09:07:03 +000056
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000057static PyObject *SelectError;
Guido van Rossumed233a51992-06-23 09:07:03 +000058
Barry Warsawc1cb3601996-12-12 22:16:21 +000059/* list of Python objects and their file descriptor */
60typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000061 PyObject *obj; /* owned reference */
62 SOCKET fd;
63 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000064} pylist;
65
Barry Warsawc1cb3601996-12-12 22:16:21 +000066static void
Tim Peters4b046c22001-08-16 21:59:46 +000067reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +000068{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000069 int i;
70 for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
71 Py_XDECREF(fd2obj[i].obj);
72 fd2obj[i].obj = NULL;
73 }
74 fd2obj[0].sentinel = -1;
Barry Warsawc1cb3601996-12-12 22:16:21 +000075}
76
77
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000078/* returns -1 and sets the Python exception if an error occurred, otherwise
79 returns a number >= 0
80*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000081static int
Brett Cannon62dba4c2003-09-10 19:37:42 +000082seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +000083{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084 int max = -1;
85 int index = 0;
Victor Stinner0fcab4a2011-01-04 12:59:15 +000086 Py_ssize_t i, len = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000087 PyObject* fast_seq = NULL;
88 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000089
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000090 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
91 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000092
Benjamin Petersone0edb8b2010-06-27 23:49:45 +000093 fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000094 if (!fast_seq)
95 return -1;
96
97 len = PySequence_Fast_GET_SIZE(fast_seq);
98
99 for (i = 0; i < len; i++) {
100 SOCKET v;
101
102 /* any intervening fileno() calls could decr this refcnt */
103 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Brett Cannon62dba4c2003-09-10 19:37:42 +0000104 return -1;
105
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000106 Py_INCREF(o);
107 v = PyObject_AsFileDescriptor( o );
108 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000109
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000110#if defined(_MSC_VER)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000111 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000112#else /* !_MSC_VER */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000113 if (v < 0 || v >= FD_SETSIZE) {
114 PyErr_SetString(PyExc_ValueError,
115 "filedescriptor out of range in select()");
116 goto finally;
117 }
118 if (v > max)
119 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000120#endif /* _MSC_VER */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000121 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000123 /* add object and its file descriptor to the list */
124 if (index >= FD_SETSIZE) {
125 PyErr_SetString(PyExc_ValueError,
126 "too many file descriptors in select()");
127 goto finally;
128 }
129 fd2obj[index].obj = o;
130 fd2obj[index].fd = v;
131 fd2obj[index].sentinel = 0;
132 fd2obj[++index].sentinel = -1;
133 }
134 Py_DECREF(fast_seq);
135 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000136
137 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000138 Py_XDECREF(o);
139 Py_DECREF(fast_seq);
140 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000141}
142
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000143/* returns NULL and sets the Python exception if an error occurred */
144static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000145set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000146{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000147 int i, j, count=0;
148 PyObject *list, *o;
149 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000151 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
152 if (FD_ISSET(fd2obj[j].fd, set))
153 count++;
154 }
155 list = PyList_New(count);
156 if (!list)
157 return NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000158
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000159 i = 0;
160 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
161 fd = fd2obj[j].fd;
162 if (FD_ISSET(fd, set)) {
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000163#ifndef _MSC_VER
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000164 if (fd > FD_SETSIZE) {
165 PyErr_SetString(PyExc_SystemError,
166 "filedescriptor out of range returned in select()");
167 goto finally;
168 }
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000169#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000170 o = fd2obj[j].obj;
171 fd2obj[j].obj = NULL;
172 /* transfer ownership */
173 if (PyList_SetItem(list, i, o) < 0)
174 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000175
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000176 i++;
177 }
178 }
179 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000180 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000181 Py_DECREF(list);
182 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000183}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000184
Barry Warsawb44740f2001-08-16 16:52:59 +0000185#undef SELECT_USES_HEAP
186#if FD_SETSIZE > 1024
187#define SELECT_USES_HEAP
188#endif /* FD_SETSIZE > 1024 */
189
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000190static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000191select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000192{
Barry Warsawb44740f2001-08-16 16:52:59 +0000193#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000194 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000195#else /* !SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000196 /* XXX: All this should probably be implemented as follows:
197 * - find the highest descriptor we're interested in
198 * - add one
199 * - that's the size
200 * See: Stevens, APitUE, $12.5.1
201 */
202 pylist rfd2obj[FD_SETSIZE + 1];
203 pylist wfd2obj[FD_SETSIZE + 1];
204 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000205#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000206 PyObject *ifdlist, *ofdlist, *efdlist;
207 PyObject *ret = NULL;
208 PyObject *tout = Py_None;
209 fd_set ifdset, ofdset, efdset;
210 double timeout;
211 struct timeval tv, *tvp;
212 long seconds;
213 int imax, omax, emax, max;
214 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000215
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000216 /* convert arguments */
217 if (!PyArg_UnpackTuple(args, "select", 3, 4,
218 &ifdlist, &ofdlist, &efdlist, &tout))
219 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000220
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000221 if (tout == Py_None)
222 tvp = (struct timeval *)0;
223 else if (!PyNumber_Check(tout)) {
224 PyErr_SetString(PyExc_TypeError,
225 "timeout must be a float or None");
226 return NULL;
227 }
228 else {
229 timeout = PyFloat_AsDouble(tout);
230 if (timeout == -1 && PyErr_Occurred())
231 return NULL;
232 if (timeout > (double)LONG_MAX) {
233 PyErr_SetString(PyExc_OverflowError,
234 "timeout period too long");
235 return NULL;
236 }
Antoine Pitrou131a6412011-04-09 23:49:58 +0200237 if (timeout < 0) {
238 PyErr_SetString(PyExc_ValueError,
239 "timeout must be non-negative");
240 return NULL;
241 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000242 seconds = (long)timeout;
243 timeout = timeout - (double)seconds;
244 tv.tv_sec = seconds;
245 tv.tv_usec = (long)(timeout * 1E6);
246 tvp = &tv;
247 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000248
Guido van Rossumed233a51992-06-23 09:07:03 +0000249
Barry Warsawb44740f2001-08-16 16:52:59 +0000250#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000251 /* Allocate memory for the lists */
252 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
253 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
254 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
255 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
256 if (rfd2obj) PyMem_DEL(rfd2obj);
257 if (wfd2obj) PyMem_DEL(wfd2obj);
258 if (efd2obj) PyMem_DEL(efd2obj);
259 return PyErr_NoMemory();
260 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000261#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000262 /* Convert sequences to fd_sets, and get maximum fd number
263 * propagates the Python exception set in seq2set()
264 */
265 rfd2obj[0].sentinel = -1;
266 wfd2obj[0].sentinel = -1;
267 efd2obj[0].sentinel = -1;
268 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
269 goto finally;
270 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
271 goto finally;
272 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
273 goto finally;
274 max = imax;
275 if (omax > max) max = omax;
276 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000277
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000278 Py_BEGIN_ALLOW_THREADS
279 n = select(max, &ifdset, &ofdset, &efdset, tvp);
280 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000281
Thomas Heller106f4c72002-09-24 16:51:00 +0000282#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000283 if (n == SOCKET_ERROR) {
284 PyErr_SetExcFromWindowsErr(SelectError, WSAGetLastError());
285 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000286#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000287 if (n < 0) {
288 PyErr_SetFromErrno(SelectError);
289 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000290#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000291 else {
292 /* any of these three calls can raise an exception. it's more
293 convenient to test for this after all three calls... but
294 is that acceptable?
295 */
296 ifdlist = set2list(&ifdset, rfd2obj);
297 ofdlist = set2list(&ofdset, wfd2obj);
298 efdlist = set2list(&efdset, efd2obj);
299 if (PyErr_Occurred())
300 ret = NULL;
301 else
302 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304 Py_DECREF(ifdlist);
305 Py_DECREF(ofdlist);
306 Py_DECREF(efdlist);
307 }
308
Barry Warsawc1cb3601996-12-12 22:16:21 +0000309 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000310 reap_obj(rfd2obj);
311 reap_obj(wfd2obj);
312 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000313#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000314 PyMem_DEL(rfd2obj);
315 PyMem_DEL(wfd2obj);
316 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000317#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000319}
320
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000321#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000323 * poll() support
324 */
325
326typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000327 PyObject_HEAD
328 PyObject *dict;
329 int ufd_uptodate;
330 int ufd_len;
331 struct pollfd *ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000332} pollObject;
333
Jeremy Hylton938ace62002-07-17 16:30:39 +0000334static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000336/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000337 contained within a pollObject. Return 1 on success, 0 on an error.
338*/
339
340static int
341update_ufd_array(pollObject *self)
342{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000343 Py_ssize_t i, pos;
344 PyObject *key, *value;
345 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000346
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000347 self->ufd_len = PyDict_Size(self->dict);
348 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
349 if (self->ufds == NULL) {
350 self->ufds = old_ufds;
351 PyErr_NoMemory();
352 return 0;
353 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000355 i = pos = 0;
356 while (PyDict_Next(self->dict, &pos, &key, &value)) {
357 self->ufds[i].fd = PyLong_AsLong(key);
358 self->ufds[i].events = (short)PyLong_AsLong(value);
359 i++;
360 }
361 self->ufd_uptodate = 1;
362 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000363}
364
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000365PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000366"register(fd [, eventmask] ) -> None\n\n\
367Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000368fd -- either an integer, or an object with a fileno() method returning an\n\
369 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000370events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000371
372static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373poll_register(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000374{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000375 PyObject *o, *key, *value;
376 int fd, events = POLLIN | POLLPRI | POLLOUT;
377 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000378
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000379 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
380 return NULL;
381 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000382
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000383 fd = PyObject_AsFileDescriptor(o);
384 if (fd == -1) return NULL;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000386 /* Add entry to the internal dictionary: the key is the
387 file descriptor, and the value is the event mask. */
388 key = PyLong_FromLong(fd);
389 if (key == NULL)
390 return NULL;
391 value = PyLong_FromLong(events);
392 if (value == NULL) {
393 Py_DECREF(key);
394 return NULL;
395 }
396 err = PyDict_SetItem(self->dict, key, value);
397 Py_DECREF(key);
398 Py_DECREF(value);
399 if (err < 0)
400 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000401
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000402 self->ufd_uptodate = 0;
403
404 Py_INCREF(Py_None);
405 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000406}
407
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000408PyDoc_STRVAR(poll_modify_doc,
409"modify(fd, eventmask) -> None\n\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000410Modify an already registered file descriptor.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000411fd -- either an integer, or an object with a fileno() method returning an\n\
412 int.\n\
413events -- an optional bitmask describing the type of events to check for");
414
415static PyObject *
416poll_modify(pollObject *self, PyObject *args)
417{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000418 PyObject *o, *key, *value;
419 int fd, events;
420 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000421
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000422 if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) {
423 return NULL;
424 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000426 fd = PyObject_AsFileDescriptor(o);
427 if (fd == -1) return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000428
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000429 /* Modify registered fd */
430 key = PyLong_FromLong(fd);
431 if (key == NULL)
432 return NULL;
433 if (PyDict_GetItem(self->dict, key) == NULL) {
434 errno = ENOENT;
435 PyErr_SetFromErrno(PyExc_IOError);
436 return NULL;
437 }
438 value = PyLong_FromLong(events);
439 if (value == NULL) {
440 Py_DECREF(key);
441 return NULL;
442 }
443 err = PyDict_SetItem(self->dict, key, value);
444 Py_DECREF(key);
445 Py_DECREF(value);
446 if (err < 0)
447 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000448
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000449 self->ufd_uptodate = 0;
450
451 Py_INCREF(Py_None);
452 return Py_None;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000453}
454
455
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000456PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000457"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000458Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000459
460static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000461poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000462{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000463 PyObject *key;
464 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000465
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000466 fd = PyObject_AsFileDescriptor( o );
467 if (fd == -1)
468 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000470 /* Check whether the fd is already in the array */
471 key = PyLong_FromLong(fd);
472 if (key == NULL)
473 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000474
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000475 if (PyDict_DelItem(self->dict, key) == -1) {
476 Py_DECREF(key);
477 /* This will simply raise the KeyError set by PyDict_DelItem
478 if the file descriptor isn't registered. */
479 return NULL;
480 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000481
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000482 Py_DECREF(key);
483 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000485 Py_INCREF(Py_None);
486 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000487}
488
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000489PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000490"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
491Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000492any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000493
494static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000495poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000496{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000497 PyObject *result_list = NULL, *tout = NULL;
498 int timeout = 0, poll_result, i, j;
499 PyObject *value = NULL, *num = NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000501 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
502 return NULL;
503 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000505 /* Check values for timeout */
506 if (tout == NULL || tout == Py_None)
507 timeout = -1;
508 else if (!PyNumber_Check(tout)) {
509 PyErr_SetString(PyExc_TypeError,
510 "timeout must be an integer or None");
511 return NULL;
512 }
513 else {
514 tout = PyNumber_Long(tout);
515 if (!tout)
516 return NULL;
517 timeout = PyLong_AsLong(tout);
518 Py_DECREF(tout);
519 if (timeout == -1 && PyErr_Occurred())
520 return NULL;
521 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000522
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000523 /* Ensure the ufd array is up to date */
524 if (!self->ufd_uptodate)
525 if (update_ufd_array(self) == 0)
526 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000527
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000528 /* call poll() */
529 Py_BEGIN_ALLOW_THREADS
530 poll_result = poll(self->ufds, self->ufd_len, timeout);
531 Py_END_ALLOW_THREADS
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000532
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000533 if (poll_result < 0) {
534 PyErr_SetFromErrno(SelectError);
535 return NULL;
536 }
537
538 /* build the result list */
539
540 result_list = PyList_New(poll_result);
541 if (!result_list)
542 return NULL;
543 else {
544 for (i = 0, j = 0; j < poll_result; j++) {
545 /* skip to the next fired descriptor */
546 while (!self->ufds[i].revents) {
547 i++;
548 }
549 /* if we hit a NULL return, set value to NULL
550 and break out of loop; code at end will
551 clean up result_list */
552 value = PyTuple_New(2);
553 if (value == NULL)
554 goto error;
555 num = PyLong_FromLong(self->ufds[i].fd);
556 if (num == NULL) {
557 Py_DECREF(value);
558 goto error;
559 }
560 PyTuple_SET_ITEM(value, 0, num);
561
562 /* The &0xffff is a workaround for AIX. 'revents'
563 is a 16-bit short, and IBM assigned POLLNVAL
564 to be 0x8000, so the conversion to int results
565 in a negative number. See SF bug #923315. */
566 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
567 if (num == NULL) {
568 Py_DECREF(value);
569 goto error;
570 }
571 PyTuple_SET_ITEM(value, 1, num);
572 if ((PyList_SetItem(result_list, j, value)) == -1) {
573 Py_DECREF(value);
574 goto error;
575 }
576 i++;
577 }
578 }
579 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000580
581 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000582 Py_DECREF(result_list);
583 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000584}
585
586static PyMethodDef poll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000587 {"register", (PyCFunction)poll_register,
588 METH_VARARGS, poll_register_doc},
589 {"modify", (PyCFunction)poll_modify,
590 METH_VARARGS, poll_modify_doc},
591 {"unregister", (PyCFunction)poll_unregister,
592 METH_O, poll_unregister_doc},
593 {"poll", (PyCFunction)poll_poll,
594 METH_VARARGS, poll_poll_doc},
595 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000596};
597
598static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000599newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000600{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000601 pollObject *self;
602 self = PyObject_New(pollObject, &poll_Type);
603 if (self == NULL)
604 return NULL;
605 /* ufd_uptodate is a Boolean, denoting whether the
606 array pointed to by ufds matches the contents of the dictionary. */
607 self->ufd_uptodate = 0;
608 self->ufds = NULL;
609 self->dict = PyDict_New();
610 if (self->dict == NULL) {
611 Py_DECREF(self);
612 return NULL;
613 }
614 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000615}
616
617static void
618poll_dealloc(pollObject *self)
619{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000620 if (self->ufds != NULL)
621 PyMem_DEL(self->ufds);
622 Py_XDECREF(self->dict);
623 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000624}
625
Tim Peters0c322792002-07-17 16:49:03 +0000626static PyTypeObject poll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000627 /* The ob_type field must be initialized in the module init function
628 * to be portable to Windows without using C++. */
629 PyVarObject_HEAD_INIT(NULL, 0)
630 "select.poll", /*tp_name*/
631 sizeof(pollObject), /*tp_basicsize*/
632 0, /*tp_itemsize*/
633 /* methods */
634 (destructor)poll_dealloc, /*tp_dealloc*/
635 0, /*tp_print*/
636 0, /*tp_getattr*/
637 0, /*tp_setattr*/
638 0, /*tp_reserved*/
639 0, /*tp_repr*/
640 0, /*tp_as_number*/
641 0, /*tp_as_sequence*/
642 0, /*tp_as_mapping*/
643 0, /*tp_hash*/
644 0, /*tp_call*/
645 0, /*tp_str*/
646 0, /*tp_getattro*/
647 0, /*tp_setattro*/
648 0, /*tp_as_buffer*/
649 Py_TPFLAGS_DEFAULT, /*tp_flags*/
650 0, /*tp_doc*/
651 0, /*tp_traverse*/
652 0, /*tp_clear*/
653 0, /*tp_richcompare*/
654 0, /*tp_weaklistoffset*/
655 0, /*tp_iter*/
656 0, /*tp_iternext*/
657 poll_methods, /*tp_methods*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000658};
659
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000660PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000661"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000662unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000663
664static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000665select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000666{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000667 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000668}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000669
670#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000671/*
Thomas Wouters477c8d52006-05-27 19:21:47 +0000672 * On some systems poll() sets errno on invalid file descriptors. We test
673 * for this at runtime because this bug may be fixed or introduced between
674 * OS releases.
675 */
676static int select_have_broken_poll(void)
677{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000678 int poll_test;
679 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +0000680
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000681 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +0000682
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000683 /* Create a file descriptor to make invalid */
684 if (pipe(filedes) < 0) {
685 return 1;
686 }
687 poll_struct.fd = filedes[0];
688 close(filedes[0]);
689 close(filedes[1]);
690 poll_test = poll(&poll_struct, 1, 0);
691 if (poll_test < 0) {
692 return 1;
693 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
694 return 1;
695 }
696 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000697}
698#endif /* __APPLE__ */
699
700#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000701
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000702#ifdef HAVE_EPOLL
703/* **************************************************************************
704 * epoll interface for Linux 2.6
705 *
706 * Written by Christian Heimes
707 * Inspired by Twisted's _epoll.pyx and select.poll()
708 */
709
710#ifdef HAVE_SYS_EPOLL_H
711#include <sys/epoll.h>
712#endif
713
714typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000715 PyObject_HEAD
716 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000717} pyEpoll_Object;
718
719static PyTypeObject pyEpoll_Type;
720#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
721
722static PyObject *
723pyepoll_err_closed(void)
724{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000725 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
726 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000727}
728
729static int
730pyepoll_internal_close(pyEpoll_Object *self)
731{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000732 int save_errno = 0;
733 if (self->epfd >= 0) {
734 int epfd = self->epfd;
735 self->epfd = -1;
736 Py_BEGIN_ALLOW_THREADS
737 if (close(epfd) < 0)
738 save_errno = errno;
739 Py_END_ALLOW_THREADS
740 }
741 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000742}
743
744static PyObject *
745newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
746{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000747 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000748
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000749 if (sizehint == -1) {
750 sizehint = FD_SETSIZE-1;
751 }
752 else if (sizehint < 1) {
753 PyErr_Format(PyExc_ValueError,
754 "sizehint must be greater zero, got %d",
755 sizehint);
756 return NULL;
757 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000758
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000759 assert(type != NULL && type->tp_alloc != NULL);
760 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
761 if (self == NULL)
762 return NULL;
763
764 if (fd == -1) {
765 Py_BEGIN_ALLOW_THREADS
766 self->epfd = epoll_create(sizehint);
767 Py_END_ALLOW_THREADS
768 }
769 else {
770 self->epfd = fd;
771 }
772 if (self->epfd < 0) {
773 Py_DECREF(self);
774 PyErr_SetFromErrno(PyExc_IOError);
775 return NULL;
776 }
777 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000778}
779
780
781static PyObject *
782pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
783{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000784 int sizehint = -1;
785 static char *kwlist[] = {"sizehint", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000786
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000787 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:epoll", kwlist,
788 &sizehint))
789 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000790
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000791 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000792}
793
794
795static void
796pyepoll_dealloc(pyEpoll_Object *self)
797{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000798 (void)pyepoll_internal_close(self);
799 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000800}
801
802static PyObject*
803pyepoll_close(pyEpoll_Object *self)
804{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000805 errno = pyepoll_internal_close(self);
806 if (errno < 0) {
807 PyErr_SetFromErrno(PyExc_IOError);
808 return NULL;
809 }
810 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000811}
812
813PyDoc_STRVAR(pyepoll_close_doc,
814"close() -> None\n\
815\n\
816Close the epoll control file descriptor. Further operations on the epoll\n\
817object will raise an exception.");
818
819static PyObject*
820pyepoll_get_closed(pyEpoll_Object *self)
821{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000822 if (self->epfd < 0)
823 Py_RETURN_TRUE;
824 else
825 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000826}
827
828static PyObject*
829pyepoll_fileno(pyEpoll_Object *self)
830{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000831 if (self->epfd < 0)
832 return pyepoll_err_closed();
833 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000834}
835
836PyDoc_STRVAR(pyepoll_fileno_doc,
837"fileno() -> int\n\
838\n\
839Return the epoll control file descriptor.");
840
841static PyObject*
842pyepoll_fromfd(PyObject *cls, PyObject *args)
843{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000844 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000845
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000846 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
847 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000848
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000849 return newPyEpoll_Object((PyTypeObject*)cls, -1, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000850}
851
852PyDoc_STRVAR(pyepoll_fromfd_doc,
853"fromfd(fd) -> epoll\n\
854\n\
855Create an epoll object from a given control fd.");
856
857static PyObject *
858pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
859{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000860 struct epoll_event ev;
861 int result;
862 int fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000863
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000864 if (epfd < 0)
865 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000866
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000867 fd = PyObject_AsFileDescriptor(pfd);
868 if (fd == -1) {
869 return NULL;
870 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000871
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000872 switch(op) {
873 case EPOLL_CTL_ADD:
874 case EPOLL_CTL_MOD:
875 ev.events = events;
876 ev.data.fd = fd;
877 Py_BEGIN_ALLOW_THREADS
878 result = epoll_ctl(epfd, op, fd, &ev);
879 Py_END_ALLOW_THREADS
880 break;
881 case EPOLL_CTL_DEL:
882 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
883 * operation required a non-NULL pointer in event, even
884 * though this argument is ignored. */
885 Py_BEGIN_ALLOW_THREADS
886 result = epoll_ctl(epfd, op, fd, &ev);
887 if (errno == EBADF) {
888 /* fd already closed */
889 result = 0;
890 errno = 0;
891 }
892 Py_END_ALLOW_THREADS
893 break;
894 default:
895 result = -1;
896 errno = EINVAL;
897 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000899 if (result < 0) {
900 PyErr_SetFromErrno(PyExc_IOError);
901 return NULL;
902 }
903 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000904}
905
906static PyObject *
907pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
908{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000909 PyObject *pfd;
910 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
911 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000912
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000913 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
914 &pfd, &events)) {
915 return NULL;
916 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000917
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000918 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000919}
920
921PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl222569d2010-08-02 20:47:56 +0000922"register(fd[, eventmask]) -> None\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000923\n\
Senthil Kumaran7d80bd12011-06-26 23:48:23 -0700924Registers a new fd or raises an IOError if the fd is already registered.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000925fd is the target file descriptor of the operation.\n\
926events is a bit set composed of the various EPOLL constants; the default\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000927is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
928\n\
929The epoll interface supports all file descriptors that support poll.");
930
931static PyObject *
932pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
933{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000934 PyObject *pfd;
935 unsigned int events;
936 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000938 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
939 &pfd, &events)) {
940 return NULL;
941 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000942
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000943 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000944}
945
946PyDoc_STRVAR(pyepoll_modify_doc,
947"modify(fd, eventmask) -> None\n\
948\n\
949fd is the target file descriptor of the operation\n\
950events is a bit set composed of the various EPOLL constants");
951
952static PyObject *
953pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
954{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000955 PyObject *pfd;
956 static char *kwlist[] = {"fd", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000957
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000958 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
959 &pfd)) {
960 return NULL;
961 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000962
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000963 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000964}
965
966PyDoc_STRVAR(pyepoll_unregister_doc,
967"unregister(fd) -> None\n\
968\n\
969fd is the target file descriptor of the operation.");
970
971static PyObject *
972pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
973{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000974 double dtimeout = -1.;
975 int timeout;
976 int maxevents = -1;
977 int nfds, i;
978 PyObject *elist = NULL, *etuple = NULL;
979 struct epoll_event *evs = NULL;
980 static char *kwlist[] = {"timeout", "maxevents", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000981
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000982 if (self->epfd < 0)
983 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000984
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000985 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
986 &dtimeout, &maxevents)) {
987 return NULL;
988 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000989
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000990 if (dtimeout < 0) {
991 timeout = -1;
992 }
993 else if (dtimeout * 1000.0 > INT_MAX) {
994 PyErr_SetString(PyExc_OverflowError,
995 "timeout is too large");
996 return NULL;
997 }
998 else {
999 timeout = (int)(dtimeout * 1000.0);
1000 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001001
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001002 if (maxevents == -1) {
1003 maxevents = FD_SETSIZE-1;
1004 }
1005 else if (maxevents < 1) {
1006 PyErr_Format(PyExc_ValueError,
1007 "maxevents must be greater than 0, got %d",
1008 maxevents);
1009 return NULL;
1010 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001011
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001012 evs = PyMem_New(struct epoll_event, maxevents);
1013 if (evs == NULL) {
1014 Py_DECREF(self);
1015 PyErr_NoMemory();
1016 return NULL;
1017 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001018
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001019 Py_BEGIN_ALLOW_THREADS
1020 nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
1021 Py_END_ALLOW_THREADS
1022 if (nfds < 0) {
1023 PyErr_SetFromErrno(PyExc_IOError);
1024 goto error;
1025 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001026
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001027 elist = PyList_New(nfds);
1028 if (elist == NULL) {
1029 goto error;
1030 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001031
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001032 for (i = 0; i < nfds; i++) {
1033 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
1034 if (etuple == NULL) {
1035 Py_CLEAR(elist);
1036 goto error;
1037 }
1038 PyList_SET_ITEM(elist, i, etuple);
1039 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001040
Christian Heimesf6cd9672008-03-26 13:45:42 +00001041 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001042 PyMem_Free(evs);
1043 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001044}
1045
1046PyDoc_STRVAR(pyepoll_poll_doc,
1047"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1048\n\
1049Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1050in seconds (as float). -1 makes poll wait indefinitely.\n\
1051Up to maxevents are returned to the caller.");
1052
1053static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001054 {"fromfd", (PyCFunction)pyepoll_fromfd,
1055 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1056 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1057 pyepoll_close_doc},
1058 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1059 pyepoll_fileno_doc},
1060 {"modify", (PyCFunction)pyepoll_modify,
1061 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1062 {"register", (PyCFunction)pyepoll_register,
1063 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1064 {"unregister", (PyCFunction)pyepoll_unregister,
1065 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1066 {"poll", (PyCFunction)pyepoll_poll,
1067 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
1068 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001069};
1070
1071static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001072 {"closed", (getter)pyepoll_get_closed, NULL,
1073 "True if the epoll handler is closed"},
1074 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001075};
1076
1077PyDoc_STRVAR(pyepoll_doc,
1078"select.epoll([sizehint=-1])\n\
1079\n\
1080Returns an epolling object\n\
1081\n\
1082sizehint must be a positive integer or -1 for the default size. The\n\
1083sizehint is used to optimize internal data structures. It doesn't limit\n\
1084the maximum number of monitored events.");
1085
1086static PyTypeObject pyEpoll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001087 PyVarObject_HEAD_INIT(NULL, 0)
1088 "select.epoll", /* tp_name */
1089 sizeof(pyEpoll_Object), /* tp_basicsize */
1090 0, /* tp_itemsize */
1091 (destructor)pyepoll_dealloc, /* tp_dealloc */
1092 0, /* tp_print */
1093 0, /* tp_getattr */
1094 0, /* tp_setattr */
1095 0, /* tp_reserved */
1096 0, /* tp_repr */
1097 0, /* tp_as_number */
1098 0, /* tp_as_sequence */
1099 0, /* tp_as_mapping */
1100 0, /* tp_hash */
1101 0, /* tp_call */
1102 0, /* tp_str */
1103 PyObject_GenericGetAttr, /* tp_getattro */
1104 0, /* tp_setattro */
1105 0, /* tp_as_buffer */
1106 Py_TPFLAGS_DEFAULT, /* tp_flags */
1107 pyepoll_doc, /* tp_doc */
1108 0, /* tp_traverse */
1109 0, /* tp_clear */
1110 0, /* tp_richcompare */
1111 0, /* tp_weaklistoffset */
1112 0, /* tp_iter */
1113 0, /* tp_iternext */
1114 pyepoll_methods, /* tp_methods */
1115 0, /* tp_members */
1116 pyepoll_getsetlist, /* tp_getset */
1117 0, /* tp_base */
1118 0, /* tp_dict */
1119 0, /* tp_descr_get */
1120 0, /* tp_descr_set */
1121 0, /* tp_dictoffset */
1122 0, /* tp_init */
1123 0, /* tp_alloc */
1124 pyepoll_new, /* tp_new */
1125 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001126};
1127
1128#endif /* HAVE_EPOLL */
1129
1130#ifdef HAVE_KQUEUE
1131/* **************************************************************************
1132 * kqueue interface for BSD
1133 *
1134 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1135 * All rights reserved.
1136 *
1137 * Redistribution and use in source and binary forms, with or without
1138 * modification, are permitted provided that the following conditions
1139 * are met:
1140 * 1. Redistributions of source code must retain the above copyright
1141 * notice, this list of conditions and the following disclaimer.
1142 * 2. Redistributions in binary form must reproduce the above copyright
1143 * notice, this list of conditions and the following disclaimer in the
1144 * documentation and/or other materials provided with the distribution.
1145 *
1146 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1147 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1148 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1149 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1150 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1151 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1152 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1153 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1154 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1155 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1156 * SUCH DAMAGE.
1157 */
1158
1159#ifdef HAVE_SYS_EVENT_H
1160#include <sys/event.h>
1161#endif
1162
1163PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001164"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001165\n\
1166This object is the equivalent of the struct kevent for the C API.\n\
1167\n\
1168See the kqueue manpage for more detailed information about the meaning\n\
1169of the arguments.\n\
1170\n\
1171One minor note: while you might hope that udata could store a\n\
1172reference to a python object, it cannot, because it is impossible to\n\
1173keep a proper reference count of the object once it's passed into the\n\
1174kernel. Therefore, I have restricted it to only storing an integer. I\n\
1175recommend ignoring it and simply using the 'ident' field to key off\n\
1176of. You could also set up a dictionary on the python side to store a\n\
1177udata->object mapping.");
1178
1179typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001180 PyObject_HEAD
1181 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001182} kqueue_event_Object;
1183
1184static PyTypeObject kqueue_event_Type;
1185
1186#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1187
1188typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001189 PyObject_HEAD
1190 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001191} kqueue_queue_Object;
1192
1193static PyTypeObject kqueue_queue_Type;
1194
1195#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1196
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001197#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1198# error uintptr_t does not match void *!
1199#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1200# define T_UINTPTRT T_ULONGLONG
1201# define T_INTPTRT T_LONGLONG
1202# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1203# define UINTPTRT_FMT_UNIT "K"
1204# define INTPTRT_FMT_UNIT "L"
1205#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1206# define T_UINTPTRT T_ULONG
1207# define T_INTPTRT T_LONG
1208# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1209# define UINTPTRT_FMT_UNIT "k"
1210# define INTPTRT_FMT_UNIT "l"
1211#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1212# define T_UINTPTRT T_UINT
1213# define T_INTPTRT T_INT
1214# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1215# define UINTPTRT_FMT_UNIT "I"
1216# define INTPTRT_FMT_UNIT "i"
1217#else
1218# error uintptr_t does not match int, long, or long long!
1219#endif
1220
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001221/* Unfortunately, we can't store python objects in udata, because
1222 * kevents in the kernel can be removed without warning, which would
1223 * forever lose the refcount on the object stored with it.
1224 */
1225
1226#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1227static struct PyMemberDef kqueue_event_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001228 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1229 {"filter", T_SHORT, KQ_OFF(e.filter)},
1230 {"flags", T_USHORT, KQ_OFF(e.flags)},
1231 {"fflags", T_UINT, KQ_OFF(e.fflags)},
1232 {"data", T_INTPTRT, KQ_OFF(e.data)},
1233 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1234 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001235};
1236#undef KQ_OFF
1237
1238static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001239
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001240kqueue_event_repr(kqueue_event_Object *s)
1241{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001242 char buf[1024];
1243 PyOS_snprintf(
1244 buf, sizeof(buf),
1245 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1246 "data=0x%zd udata=%p>",
1247 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1248 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1249 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001250}
1251
1252static int
1253kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1254{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001255 PyObject *pfd;
1256 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1257 "data", "udata", NULL};
1258 static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001260 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001261
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1263 &pfd, &(self->e.filter), &(self->e.flags),
1264 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1265 return -1;
1266 }
1267
1268 if (PyLong_Check(pfd)) {
1269 self->e.ident = PyLong_AsUintptr_t(pfd);
1270 }
1271 else {
1272 self->e.ident = PyObject_AsFileDescriptor(pfd);
1273 }
1274 if (PyErr_Occurred()) {
1275 return -1;
1276 }
1277 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001278}
1279
1280static PyObject *
1281kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001282 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001283{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001284 Py_intptr_t result = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001285
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001286 if (!kqueue_event_Check(o)) {
1287 if (op == Py_EQ || op == Py_NE) {
1288 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1289 Py_INCREF(res);
1290 return res;
1291 }
1292 PyErr_Format(PyExc_TypeError,
1293 "can't compare %.200s to %.200s",
1294 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1295 return NULL;
1296 }
1297 if (((result = s->e.ident - o->e.ident) == 0) &&
1298 ((result = s->e.filter - o->e.filter) == 0) &&
1299 ((result = s->e.flags - o->e.flags) == 0) &&
1300 ((result = s->e.fflags - o->e.fflags) == 0) &&
1301 ((result = s->e.data - o->e.data) == 0) &&
1302 ((result = s->e.udata - o->e.udata) == 0)
1303 ) {
1304 result = 0;
1305 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001306
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001307 switch (op) {
1308 case Py_EQ:
1309 result = (result == 0);
1310 break;
1311 case Py_NE:
1312 result = (result != 0);
1313 break;
1314 case Py_LE:
1315 result = (result <= 0);
1316 break;
1317 case Py_GE:
1318 result = (result >= 0);
1319 break;
1320 case Py_LT:
1321 result = (result < 0);
1322 break;
1323 case Py_GT:
1324 result = (result > 0);
1325 break;
1326 }
1327 return PyBool_FromLong((long)result);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001328}
1329
1330static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001331 PyVarObject_HEAD_INIT(NULL, 0)
1332 "select.kevent", /* tp_name */
1333 sizeof(kqueue_event_Object), /* tp_basicsize */
1334 0, /* tp_itemsize */
1335 0, /* tp_dealloc */
1336 0, /* tp_print */
1337 0, /* tp_getattr */
1338 0, /* tp_setattr */
1339 0, /* tp_reserved */
1340 (reprfunc)kqueue_event_repr, /* tp_repr */
1341 0, /* tp_as_number */
1342 0, /* tp_as_sequence */
1343 0, /* tp_as_mapping */
1344 0, /* tp_hash */
1345 0, /* tp_call */
1346 0, /* tp_str */
1347 0, /* tp_getattro */
1348 0, /* tp_setattro */
1349 0, /* tp_as_buffer */
1350 Py_TPFLAGS_DEFAULT, /* tp_flags */
1351 kqueue_event_doc, /* tp_doc */
1352 0, /* tp_traverse */
1353 0, /* tp_clear */
1354 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1355 0, /* tp_weaklistoffset */
1356 0, /* tp_iter */
1357 0, /* tp_iternext */
1358 0, /* tp_methods */
1359 kqueue_event_members, /* tp_members */
1360 0, /* tp_getset */
1361 0, /* tp_base */
1362 0, /* tp_dict */
1363 0, /* tp_descr_get */
1364 0, /* tp_descr_set */
1365 0, /* tp_dictoffset */
1366 (initproc)kqueue_event_init, /* tp_init */
1367 0, /* tp_alloc */
1368 0, /* tp_new */
1369 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001370};
1371
1372static PyObject *
1373kqueue_queue_err_closed(void)
1374{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1376 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001377}
1378
1379static int
1380kqueue_queue_internal_close(kqueue_queue_Object *self)
1381{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001382 int save_errno = 0;
1383 if (self->kqfd >= 0) {
1384 int kqfd = self->kqfd;
1385 self->kqfd = -1;
1386 Py_BEGIN_ALLOW_THREADS
1387 if (close(kqfd) < 0)
1388 save_errno = errno;
1389 Py_END_ALLOW_THREADS
1390 }
1391 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001392}
1393
1394static PyObject *
1395newKqueue_Object(PyTypeObject *type, SOCKET fd)
1396{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001397 kqueue_queue_Object *self;
1398 assert(type != NULL && type->tp_alloc != NULL);
1399 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1400 if (self == NULL) {
1401 return NULL;
1402 }
1403
1404 if (fd == -1) {
1405 Py_BEGIN_ALLOW_THREADS
1406 self->kqfd = kqueue();
1407 Py_END_ALLOW_THREADS
1408 }
1409 else {
1410 self->kqfd = fd;
1411 }
1412 if (self->kqfd < 0) {
1413 Py_DECREF(self);
1414 PyErr_SetFromErrno(PyExc_IOError);
1415 return NULL;
1416 }
1417 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001418}
1419
1420static PyObject *
1421kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1422{
1423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001424 if ((args != NULL && PyObject_Size(args)) ||
1425 (kwds != NULL && PyObject_Size(kwds))) {
1426 PyErr_SetString(PyExc_ValueError,
1427 "select.kqueue doesn't accept arguments");
1428 return NULL;
1429 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001431 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001432}
1433
1434static void
1435kqueue_queue_dealloc(kqueue_queue_Object *self)
1436{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001437 kqueue_queue_internal_close(self);
1438 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001439}
1440
1441static PyObject*
1442kqueue_queue_close(kqueue_queue_Object *self)
1443{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001444 errno = kqueue_queue_internal_close(self);
1445 if (errno < 0) {
1446 PyErr_SetFromErrno(PyExc_IOError);
1447 return NULL;
1448 }
1449 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001450}
1451
1452PyDoc_STRVAR(kqueue_queue_close_doc,
1453"close() -> None\n\
1454\n\
1455Close the kqueue control file descriptor. Further operations on the kqueue\n\
1456object will raise an exception.");
1457
1458static PyObject*
1459kqueue_queue_get_closed(kqueue_queue_Object *self)
1460{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001461 if (self->kqfd < 0)
1462 Py_RETURN_TRUE;
1463 else
1464 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001465}
1466
1467static PyObject*
1468kqueue_queue_fileno(kqueue_queue_Object *self)
1469{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001470 if (self->kqfd < 0)
1471 return kqueue_queue_err_closed();
1472 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001473}
1474
1475PyDoc_STRVAR(kqueue_queue_fileno_doc,
1476"fileno() -> int\n\
1477\n\
1478Return the kqueue control file descriptor.");
1479
1480static PyObject*
1481kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1482{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001483 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001485 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1486 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001487
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001488 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001489}
1490
1491PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1492"fromfd(fd) -> kqueue\n\
1493\n\
1494Create a kqueue object from a given control fd.");
1495
1496static PyObject *
1497kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1498{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001499 int nevents = 0;
1500 int gotevents = 0;
1501 int nchanges = 0;
1502 int i = 0;
1503 PyObject *otimeout = NULL;
1504 PyObject *ch = NULL;
1505 PyObject *it = NULL, *ei = NULL;
1506 PyObject *result = NULL;
1507 struct kevent *evl = NULL;
1508 struct kevent *chl = NULL;
1509 struct timespec timeoutspec;
1510 struct timespec *ptimeoutspec;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001512 if (self->kqfd < 0)
1513 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001514
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001515 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1516 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001517
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001518 if (nevents < 0) {
1519 PyErr_Format(PyExc_ValueError,
1520 "Length of eventlist must be 0 or positive, got %d",
1521 nevents);
1522 return NULL;
1523 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001524
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001525 if (otimeout == Py_None || otimeout == NULL) {
1526 ptimeoutspec = NULL;
1527 }
1528 else if (PyNumber_Check(otimeout)) {
1529 double timeout;
1530 long seconds;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001531
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001532 timeout = PyFloat_AsDouble(otimeout);
1533 if (timeout == -1 && PyErr_Occurred())
1534 return NULL;
1535 if (timeout > (double)LONG_MAX) {
1536 PyErr_SetString(PyExc_OverflowError,
1537 "timeout period too long");
1538 return NULL;
1539 }
1540 if (timeout < 0) {
1541 PyErr_SetString(PyExc_ValueError,
1542 "timeout must be positive or None");
1543 return NULL;
1544 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001545
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001546 seconds = (long)timeout;
1547 timeout = timeout - (double)seconds;
1548 timeoutspec.tv_sec = seconds;
1549 timeoutspec.tv_nsec = (long)(timeout * 1E9);
1550 ptimeoutspec = &timeoutspec;
1551 }
1552 else {
1553 PyErr_Format(PyExc_TypeError,
1554 "timeout argument must be an number "
1555 "or None, got %.200s",
1556 Py_TYPE(otimeout)->tp_name);
1557 return NULL;
1558 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001559
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001560 if (ch != NULL && ch != Py_None) {
1561 it = PyObject_GetIter(ch);
1562 if (it == NULL) {
1563 PyErr_SetString(PyExc_TypeError,
1564 "changelist is not iterable");
1565 return NULL;
1566 }
1567 nchanges = PyObject_Size(ch);
1568 if (nchanges < 0) {
1569 goto error;
1570 }
Georg Brandlc0e22b72010-03-14 10:51:01 +00001571
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001572 chl = PyMem_New(struct kevent, nchanges);
1573 if (chl == NULL) {
1574 PyErr_NoMemory();
1575 goto error;
1576 }
1577 i = 0;
1578 while ((ei = PyIter_Next(it)) != NULL) {
1579 if (!kqueue_event_Check(ei)) {
1580 Py_DECREF(ei);
1581 PyErr_SetString(PyExc_TypeError,
1582 "changelist must be an iterable of "
1583 "select.kevent objects");
1584 goto error;
1585 } else {
1586 chl[i++] = ((kqueue_event_Object *)ei)->e;
1587 }
1588 Py_DECREF(ei);
1589 }
1590 }
1591 Py_CLEAR(it);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001592
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001593 /* event list */
1594 if (nevents) {
1595 evl = PyMem_New(struct kevent, nevents);
1596 if (evl == NULL) {
1597 PyErr_NoMemory();
1598 goto error;
1599 }
1600 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001601
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001602 Py_BEGIN_ALLOW_THREADS
1603 gotevents = kevent(self->kqfd, chl, nchanges,
1604 evl, nevents, ptimeoutspec);
1605 Py_END_ALLOW_THREADS
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001606
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001607 if (gotevents == -1) {
1608 PyErr_SetFromErrno(PyExc_OSError);
1609 goto error;
1610 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001611
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001612 result = PyList_New(gotevents);
1613 if (result == NULL) {
1614 goto error;
1615 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001616
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001617 for (i = 0; i < gotevents; i++) {
1618 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001619
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001620 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1621 if (ch == NULL) {
1622 goto error;
1623 }
1624 ch->e = evl[i];
1625 PyList_SET_ITEM(result, i, (PyObject *)ch);
1626 }
1627 PyMem_Free(chl);
1628 PyMem_Free(evl);
1629 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001630
1631 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001632 PyMem_Free(chl);
1633 PyMem_Free(evl);
1634 Py_XDECREF(result);
1635 Py_XDECREF(it);
1636 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001637}
1638
1639PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00001640"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001641\n\
1642Calls the kernel kevent function.\n\
1643- changelist must be a list of kevent objects describing the changes\n\
1644 to be made to the kernel's watch list or None.\n\
1645- max_events lets you specify the maximum number of events that the\n\
1646 kernel will return.\n\
1647- timeout is the maximum time to wait in seconds, or else None,\n\
1648 to wait forever. timeout accepts floats for smaller timeouts, too.");
1649
1650
1651static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001652 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
1653 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
1654 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
1655 kqueue_queue_close_doc},
1656 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
1657 kqueue_queue_fileno_doc},
1658 {"control", (PyCFunction)kqueue_queue_control,
1659 METH_VARARGS , kqueue_queue_control_doc},
1660 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001661};
1662
1663static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001664 {"closed", (getter)kqueue_queue_get_closed, NULL,
1665 "True if the kqueue handler is closed"},
1666 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001667};
1668
1669PyDoc_STRVAR(kqueue_queue_doc,
1670"Kqueue syscall wrapper.\n\
1671\n\
1672For example, to start watching a socket for input:\n\
1673>>> kq = kqueue()\n\
1674>>> sock = socket()\n\
1675>>> sock.connect((host, port))\n\
1676>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
1677\n\
1678To wait one second for it to become writeable:\n\
1679>>> kq.control(None, 1, 1000)\n\
1680\n\
1681To stop listening:\n\
1682>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
1683
1684static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001685 PyVarObject_HEAD_INIT(NULL, 0)
1686 "select.kqueue", /* tp_name */
1687 sizeof(kqueue_queue_Object), /* tp_basicsize */
1688 0, /* tp_itemsize */
1689 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
1690 0, /* tp_print */
1691 0, /* tp_getattr */
1692 0, /* tp_setattr */
1693 0, /* tp_reserved */
1694 0, /* tp_repr */
1695 0, /* tp_as_number */
1696 0, /* tp_as_sequence */
1697 0, /* tp_as_mapping */
1698 0, /* tp_hash */
1699 0, /* tp_call */
1700 0, /* tp_str */
1701 0, /* tp_getattro */
1702 0, /* tp_setattro */
1703 0, /* tp_as_buffer */
1704 Py_TPFLAGS_DEFAULT, /* tp_flags */
1705 kqueue_queue_doc, /* tp_doc */
1706 0, /* tp_traverse */
1707 0, /* tp_clear */
1708 0, /* tp_richcompare */
1709 0, /* tp_weaklistoffset */
1710 0, /* tp_iter */
1711 0, /* tp_iternext */
1712 kqueue_queue_methods, /* tp_methods */
1713 0, /* tp_members */
1714 kqueue_queue_getsetlist, /* tp_getset */
1715 0, /* tp_base */
1716 0, /* tp_dict */
1717 0, /* tp_descr_get */
1718 0, /* tp_descr_set */
1719 0, /* tp_dictoffset */
1720 0, /* tp_init */
1721 0, /* tp_alloc */
1722 kqueue_queue_new, /* tp_new */
1723 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001724};
1725
1726#endif /* HAVE_KQUEUE */
1727/* ************************************************************************ */
1728
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001729PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001730"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
1731\n\
1732Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00001733The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001734rlist -- wait until ready for reading\n\
1735wlist -- wait until ready for writing\n\
1736xlist -- wait for an ``exceptional condition''\n\
1737If only one kind of condition is required, pass [] for the other lists.\n\
1738A file descriptor is either a socket or file object, or a small integer\n\
1739gotten from a fileno() method call on one of those.\n\
1740\n\
1741The optional 4th argument specifies a timeout in seconds; it may be\n\
1742a floating point number to specify fractions of seconds. If it is absent\n\
1743or None, the call will never time out.\n\
1744\n\
1745The return value is a tuple of three lists corresponding to the first three\n\
1746arguments; each contains the subset of the corresponding file descriptors\n\
1747that are ready.\n\
1748\n\
1749*** IMPORTANT NOTICE ***\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001750On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001751descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001752
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00001753static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001754 {"select", select_select, METH_VARARGS, select_doc},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001755#ifdef HAVE_POLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001756 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00001757#endif /* HAVE_POLL */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001758 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00001759};
1760
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001761PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001762"This module supports asynchronous I/O on multiple file descriptors.\n\
1763\n\
1764*** IMPORTANT NOTICE ***\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001765On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00001766
Martin v. Löwis1a214512008-06-11 05:26:20 +00001767
1768static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001769 PyModuleDef_HEAD_INIT,
1770 "select",
1771 module_doc,
1772 -1,
1773 select_methods,
1774 NULL,
1775 NULL,
1776 NULL,
1777 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001778};
1779
Mark Hammond62b1ab12002-07-23 06:31:15 +00001780PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001781PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00001782{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001783 PyObject *m;
1784 m = PyModule_Create(&selectmodule);
1785 if (m == NULL)
1786 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00001787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001788 SelectError = PyErr_NewException("select.error", NULL, NULL);
1789 Py_INCREF(SelectError);
1790 PyModule_AddObject(m, "error", SelectError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001791
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00001792#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00001793#ifdef HAVE_BROKEN_PIPE_BUF
1794#undef PIPE_BUF
1795#define PIPE_BUF 512
1796#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001797 PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00001798#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00001799
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001800#if defined(HAVE_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001801#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001802 if (select_have_broken_poll()) {
1803 if (PyObject_DelAttrString(m, "poll") == -1) {
1804 PyErr_Clear();
1805 }
1806 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001807#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001808 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001809#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001810 if (PyType_Ready(&poll_Type) < 0)
1811 return NULL;
1812 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
1813 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
1814 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
1815 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
1816 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
1817 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001818
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001819#ifdef POLLRDNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001820 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001821#endif
1822#ifdef POLLRDBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001823 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001824#endif
1825#ifdef POLLWRNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001826 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001827#endif
1828#ifdef POLLWRBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001829 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001830#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001831#ifdef POLLMSG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001832 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001833#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001834 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001835#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001836
1837#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001838 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
1839 if (PyType_Ready(&pyEpoll_Type) < 0)
1840 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001841
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001842 Py_INCREF(&pyEpoll_Type);
1843 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001844
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001845 PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
1846 PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
1847 PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
1848 PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
1849 PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
1850 PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001851#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001852 /* Kernel 2.6.2+ */
1853 PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001854#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001855 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
1856 PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
1857 PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
1858 PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
1859 PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
1860 PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001861#endif /* HAVE_EPOLL */
1862
1863#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864 kqueue_event_Type.tp_new = PyType_GenericNew;
1865 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
1866 if(PyType_Ready(&kqueue_event_Type) < 0)
1867 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001868
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001869 Py_INCREF(&kqueue_event_Type);
1870 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001871
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001872 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
1873 if(PyType_Ready(&kqueue_queue_Type) < 0)
1874 return NULL;
1875 Py_INCREF(&kqueue_queue_Type);
1876 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
1877
1878 /* event filters */
1879 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
1880 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
1881 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
1882 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
1883 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001884#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001886#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
1888 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001889
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001890 /* event flags */
1891 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
1892 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
1893 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
1894 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
1895 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
1896 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001897
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001898 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
1899 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001900
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001901 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
1902 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001903
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001904 /* READ WRITE filter flag */
1905 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001906
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001907 /* VNODE filter flags */
1908 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
1909 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
1910 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
1911 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
1912 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
1913 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
1914 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001915
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001916 /* PROC filter flags */
1917 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
1918 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
1919 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
1920 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
1921 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001922
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001923 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
1924 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
1925 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
1926
1927 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001928#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001929 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
1930 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
1931 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001932#endif
1933
1934#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001935 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00001936}