blob: 0736215972d7e30935610c1d353e6a315dd955ac [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;
Antoine Pitroue4ad37e2012-11-01 20:13:54 +010086 Py_ssize_t i;
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
Antoine Pitroue4ad37e2012-11-01 20:13:54 +010097 for (i = 0; i < PySequence_Fast_GET_SIZE(fast_seq); i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000098 SOCKET v;
99
100 /* any intervening fileno() calls could decr this refcnt */
101 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Jesus Cea62a5c322012-07-19 21:31:26 +0200102 goto finally;
Brett Cannon62dba4c2003-09-10 19:37:42 +0000103
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000104 Py_INCREF(o);
105 v = PyObject_AsFileDescriptor( o );
106 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000107
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000108#if defined(_MSC_VER)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000109 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000110#else /* !_MSC_VER */
Charles-François Nataliaa26b272011-08-28 17:51:43 +0200111 if (!_PyIsSelectable_fd(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000112 PyErr_SetString(PyExc_ValueError,
113 "filedescriptor out of range in select()");
114 goto finally;
115 }
116 if (v > max)
117 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000118#endif /* _MSC_VER */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000119 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000120
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000121 /* add object and its file descriptor to the list */
122 if (index >= FD_SETSIZE) {
123 PyErr_SetString(PyExc_ValueError,
124 "too many file descriptors in select()");
125 goto finally;
126 }
127 fd2obj[index].obj = o;
128 fd2obj[index].fd = v;
129 fd2obj[index].sentinel = 0;
130 fd2obj[++index].sentinel = -1;
131 }
132 Py_DECREF(fast_seq);
133 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000134
135 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000136 Py_XDECREF(o);
137 Py_DECREF(fast_seq);
138 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000139}
140
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000141/* returns NULL and sets the Python exception if an error occurred */
142static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000143set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000144{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000145 int i, j, count=0;
146 PyObject *list, *o;
147 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000148
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000149 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
150 if (FD_ISSET(fd2obj[j].fd, set))
151 count++;
152 }
153 list = PyList_New(count);
154 if (!list)
155 return NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000156
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000157 i = 0;
158 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
159 fd = fd2obj[j].fd;
160 if (FD_ISSET(fd, set)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000161 o = fd2obj[j].obj;
162 fd2obj[j].obj = NULL;
163 /* transfer ownership */
164 if (PyList_SetItem(list, i, o) < 0)
165 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000166
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000167 i++;
168 }
169 }
170 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000171 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000172 Py_DECREF(list);
173 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000174}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000175
Barry Warsawb44740f2001-08-16 16:52:59 +0000176#undef SELECT_USES_HEAP
177#if FD_SETSIZE > 1024
178#define SELECT_USES_HEAP
179#endif /* FD_SETSIZE > 1024 */
180
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000181static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000182select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000183{
Barry Warsawb44740f2001-08-16 16:52:59 +0000184#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000185 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000186#else /* !SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000187 /* XXX: All this should probably be implemented as follows:
188 * - find the highest descriptor we're interested in
189 * - add one
190 * - that's the size
191 * See: Stevens, APitUE, $12.5.1
192 */
193 pylist rfd2obj[FD_SETSIZE + 1];
194 pylist wfd2obj[FD_SETSIZE + 1];
195 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000196#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000197 PyObject *ifdlist, *ofdlist, *efdlist;
198 PyObject *ret = NULL;
199 PyObject *tout = Py_None;
200 fd_set ifdset, ofdset, efdset;
201 double timeout;
202 struct timeval tv, *tvp;
203 long seconds;
204 int imax, omax, emax, max;
205 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 /* convert arguments */
208 if (!PyArg_UnpackTuple(args, "select", 3, 4,
209 &ifdlist, &ofdlist, &efdlist, &tout))
210 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000211
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000212 if (tout == Py_None)
213 tvp = (struct timeval *)0;
214 else if (!PyNumber_Check(tout)) {
215 PyErr_SetString(PyExc_TypeError,
216 "timeout must be a float or None");
217 return NULL;
218 }
219 else {
220 timeout = PyFloat_AsDouble(tout);
221 if (timeout == -1 && PyErr_Occurred())
222 return NULL;
223 if (timeout > (double)LONG_MAX) {
224 PyErr_SetString(PyExc_OverflowError,
225 "timeout period too long");
226 return NULL;
227 }
228 seconds = (long)timeout;
229 timeout = timeout - (double)seconds;
230 tv.tv_sec = seconds;
231 tv.tv_usec = (long)(timeout * 1E6);
232 tvp = &tv;
233 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000234
Guido van Rossumed233a51992-06-23 09:07:03 +0000235
Barry Warsawb44740f2001-08-16 16:52:59 +0000236#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000237 /* Allocate memory for the lists */
238 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
239 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
240 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
241 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
242 if (rfd2obj) PyMem_DEL(rfd2obj);
243 if (wfd2obj) PyMem_DEL(wfd2obj);
244 if (efd2obj) PyMem_DEL(efd2obj);
245 return PyErr_NoMemory();
246 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000247#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000248 /* Convert sequences to fd_sets, and get maximum fd number
249 * propagates the Python exception set in seq2set()
250 */
251 rfd2obj[0].sentinel = -1;
252 wfd2obj[0].sentinel = -1;
253 efd2obj[0].sentinel = -1;
254 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
255 goto finally;
256 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
257 goto finally;
258 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
259 goto finally;
260 max = imax;
261 if (omax > max) max = omax;
262 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000264 Py_BEGIN_ALLOW_THREADS
265 n = select(max, &ifdset, &ofdset, &efdset, tvp);
266 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000267
Thomas Heller106f4c72002-09-24 16:51:00 +0000268#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000269 if (n == SOCKET_ERROR) {
270 PyErr_SetExcFromWindowsErr(SelectError, WSAGetLastError());
271 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000272#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000273 if (n < 0) {
274 PyErr_SetFromErrno(SelectError);
275 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000276#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000277 else {
278 /* any of these three calls can raise an exception. it's more
279 convenient to test for this after all three calls... but
280 is that acceptable?
281 */
282 ifdlist = set2list(&ifdset, rfd2obj);
283 ofdlist = set2list(&ofdset, wfd2obj);
284 efdlist = set2list(&efdset, efd2obj);
285 if (PyErr_Occurred())
286 ret = NULL;
287 else
288 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000289
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000290 Py_DECREF(ifdlist);
291 Py_DECREF(ofdlist);
292 Py_DECREF(efdlist);
293 }
294
Barry Warsawc1cb3601996-12-12 22:16:21 +0000295 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000296 reap_obj(rfd2obj);
297 reap_obj(wfd2obj);
298 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000299#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000300 PyMem_DEL(rfd2obj);
301 PyMem_DEL(wfd2obj);
302 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000303#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000305}
306
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000307#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000308/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000309 * poll() support
310 */
311
312typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 PyObject_HEAD
314 PyObject *dict;
315 int ufd_uptodate;
316 int ufd_len;
317 struct pollfd *ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000318} pollObject;
319
Jeremy Hylton938ace62002-07-17 16:30:39 +0000320static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000321
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000323 contained within a pollObject. Return 1 on success, 0 on an error.
324*/
325
326static int
327update_ufd_array(pollObject *self)
328{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000329 Py_ssize_t i, pos;
330 PyObject *key, *value;
331 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000332
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000333 self->ufd_len = PyDict_Size(self->dict);
334 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
335 if (self->ufds == NULL) {
336 self->ufds = old_ufds;
337 PyErr_NoMemory();
338 return 0;
339 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000340
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000341 i = pos = 0;
342 while (PyDict_Next(self->dict, &pos, &key, &value)) {
343 self->ufds[i].fd = PyLong_AsLong(key);
344 self->ufds[i].events = (short)PyLong_AsLong(value);
345 i++;
346 }
347 self->ufd_uptodate = 1;
348 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000349}
350
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000351PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000352"register(fd [, eventmask] ) -> None\n\n\
353Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000354fd -- either an integer, or an object with a fileno() method returning an\n\
355 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000356events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000357
358static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000359poll_register(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000360{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000361 PyObject *o, *key, *value;
362 int fd, events = POLLIN | POLLPRI | POLLOUT;
363 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000364
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000365 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
366 return NULL;
367 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000368
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000369 fd = PyObject_AsFileDescriptor(o);
370 if (fd == -1) return NULL;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000371
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000372 /* Add entry to the internal dictionary: the key is the
373 file descriptor, and the value is the event mask. */
374 key = PyLong_FromLong(fd);
375 if (key == NULL)
376 return NULL;
377 value = PyLong_FromLong(events);
378 if (value == NULL) {
379 Py_DECREF(key);
380 return NULL;
381 }
382 err = PyDict_SetItem(self->dict, key, value);
383 Py_DECREF(key);
384 Py_DECREF(value);
385 if (err < 0)
386 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000388 self->ufd_uptodate = 0;
389
390 Py_INCREF(Py_None);
391 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000392}
393
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000394PyDoc_STRVAR(poll_modify_doc,
395"modify(fd, eventmask) -> None\n\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000396Modify an already registered file descriptor.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000397fd -- either an integer, or an object with a fileno() method returning an\n\
398 int.\n\
399events -- an optional bitmask describing the type of events to check for");
400
401static PyObject *
402poll_modify(pollObject *self, PyObject *args)
403{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000404 PyObject *o, *key, *value;
405 int fd, events;
406 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000408 if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) {
409 return NULL;
410 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000411
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000412 fd = PyObject_AsFileDescriptor(o);
413 if (fd == -1) return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000414
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000415 /* Modify registered fd */
416 key = PyLong_FromLong(fd);
417 if (key == NULL)
418 return NULL;
419 if (PyDict_GetItem(self->dict, key) == NULL) {
420 errno = ENOENT;
421 PyErr_SetFromErrno(PyExc_IOError);
Jesus Cea62a5c322012-07-19 21:31:26 +0200422 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000423 return NULL;
424 }
425 value = PyLong_FromLong(events);
426 if (value == NULL) {
427 Py_DECREF(key);
428 return NULL;
429 }
430 err = PyDict_SetItem(self->dict, key, value);
431 Py_DECREF(key);
432 Py_DECREF(value);
433 if (err < 0)
434 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000436 self->ufd_uptodate = 0;
437
438 Py_INCREF(Py_None);
439 return Py_None;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000440}
441
442
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000443PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000444"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000445Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000446
447static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000448poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000449{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000450 PyObject *key;
451 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000452
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000453 fd = PyObject_AsFileDescriptor( o );
454 if (fd == -1)
455 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000456
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000457 /* Check whether the fd is already in the array */
458 key = PyLong_FromLong(fd);
459 if (key == NULL)
460 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000461
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000462 if (PyDict_DelItem(self->dict, key) == -1) {
463 Py_DECREF(key);
464 /* This will simply raise the KeyError set by PyDict_DelItem
465 if the file descriptor isn't registered. */
466 return NULL;
467 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000468
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000469 Py_DECREF(key);
470 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000471
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000472 Py_INCREF(Py_None);
473 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000474}
475
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000476PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000477"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
478Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000479any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000480
481static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000482poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000483{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 PyObject *result_list = NULL, *tout = NULL;
485 int timeout = 0, poll_result, i, j;
486 PyObject *value = NULL, *num = NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000487
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000488 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
489 return NULL;
490 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000491
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000492 /* Check values for timeout */
493 if (tout == NULL || tout == Py_None)
494 timeout = -1;
495 else if (!PyNumber_Check(tout)) {
496 PyErr_SetString(PyExc_TypeError,
497 "timeout must be an integer or None");
498 return NULL;
499 }
500 else {
501 tout = PyNumber_Long(tout);
502 if (!tout)
503 return NULL;
504 timeout = PyLong_AsLong(tout);
505 Py_DECREF(tout);
506 if (timeout == -1 && PyErr_Occurred())
507 return NULL;
508 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000509
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000510 /* Ensure the ufd array is up to date */
511 if (!self->ufd_uptodate)
512 if (update_ufd_array(self) == 0)
513 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000514
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000515 /* call poll() */
516 Py_BEGIN_ALLOW_THREADS
517 poll_result = poll(self->ufds, self->ufd_len, timeout);
518 Py_END_ALLOW_THREADS
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000519
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000520 if (poll_result < 0) {
521 PyErr_SetFromErrno(SelectError);
522 return NULL;
523 }
524
525 /* build the result list */
526
527 result_list = PyList_New(poll_result);
528 if (!result_list)
529 return NULL;
530 else {
531 for (i = 0, j = 0; j < poll_result; j++) {
532 /* skip to the next fired descriptor */
533 while (!self->ufds[i].revents) {
534 i++;
535 }
536 /* if we hit a NULL return, set value to NULL
537 and break out of loop; code at end will
538 clean up result_list */
539 value = PyTuple_New(2);
540 if (value == NULL)
541 goto error;
542 num = PyLong_FromLong(self->ufds[i].fd);
543 if (num == NULL) {
544 Py_DECREF(value);
545 goto error;
546 }
547 PyTuple_SET_ITEM(value, 0, num);
548
549 /* The &0xffff is a workaround for AIX. 'revents'
550 is a 16-bit short, and IBM assigned POLLNVAL
551 to be 0x8000, so the conversion to int results
552 in a negative number. See SF bug #923315. */
553 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
554 if (num == NULL) {
555 Py_DECREF(value);
556 goto error;
557 }
558 PyTuple_SET_ITEM(value, 1, num);
559 if ((PyList_SetItem(result_list, j, value)) == -1) {
560 Py_DECREF(value);
561 goto error;
562 }
563 i++;
564 }
565 }
566 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000567
568 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000569 Py_DECREF(result_list);
570 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000571}
572
573static PyMethodDef poll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000574 {"register", (PyCFunction)poll_register,
575 METH_VARARGS, poll_register_doc},
576 {"modify", (PyCFunction)poll_modify,
577 METH_VARARGS, poll_modify_doc},
578 {"unregister", (PyCFunction)poll_unregister,
579 METH_O, poll_unregister_doc},
580 {"poll", (PyCFunction)poll_poll,
581 METH_VARARGS, poll_poll_doc},
582 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000583};
584
585static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000586newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000587{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000588 pollObject *self;
589 self = PyObject_New(pollObject, &poll_Type);
590 if (self == NULL)
591 return NULL;
592 /* ufd_uptodate is a Boolean, denoting whether the
593 array pointed to by ufds matches the contents of the dictionary. */
594 self->ufd_uptodate = 0;
595 self->ufds = NULL;
596 self->dict = PyDict_New();
597 if (self->dict == NULL) {
598 Py_DECREF(self);
599 return NULL;
600 }
601 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000602}
603
604static void
605poll_dealloc(pollObject *self)
606{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000607 if (self->ufds != NULL)
608 PyMem_DEL(self->ufds);
609 Py_XDECREF(self->dict);
610 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000611}
612
Tim Peters0c322792002-07-17 16:49:03 +0000613static PyTypeObject poll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000614 /* The ob_type field must be initialized in the module init function
615 * to be portable to Windows without using C++. */
616 PyVarObject_HEAD_INIT(NULL, 0)
617 "select.poll", /*tp_name*/
618 sizeof(pollObject), /*tp_basicsize*/
619 0, /*tp_itemsize*/
620 /* methods */
621 (destructor)poll_dealloc, /*tp_dealloc*/
622 0, /*tp_print*/
623 0, /*tp_getattr*/
624 0, /*tp_setattr*/
625 0, /*tp_reserved*/
626 0, /*tp_repr*/
627 0, /*tp_as_number*/
628 0, /*tp_as_sequence*/
629 0, /*tp_as_mapping*/
630 0, /*tp_hash*/
631 0, /*tp_call*/
632 0, /*tp_str*/
633 0, /*tp_getattro*/
634 0, /*tp_setattro*/
635 0, /*tp_as_buffer*/
636 Py_TPFLAGS_DEFAULT, /*tp_flags*/
637 0, /*tp_doc*/
638 0, /*tp_traverse*/
639 0, /*tp_clear*/
640 0, /*tp_richcompare*/
641 0, /*tp_weaklistoffset*/
642 0, /*tp_iter*/
643 0, /*tp_iternext*/
644 poll_methods, /*tp_methods*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000645};
646
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000647PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000648"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000649unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000650
651static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000652select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000653{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000654 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000655}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000656
657#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000658/*
Thomas Wouters477c8d52006-05-27 19:21:47 +0000659 * On some systems poll() sets errno on invalid file descriptors. We test
660 * for this at runtime because this bug may be fixed or introduced between
661 * OS releases.
662 */
663static int select_have_broken_poll(void)
664{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000665 int poll_test;
666 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +0000667
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000668 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +0000669
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000670 /* Create a file descriptor to make invalid */
671 if (pipe(filedes) < 0) {
672 return 1;
673 }
674 poll_struct.fd = filedes[0];
675 close(filedes[0]);
676 close(filedes[1]);
677 poll_test = poll(&poll_struct, 1, 0);
678 if (poll_test < 0) {
679 return 1;
680 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
681 return 1;
682 }
683 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000684}
685#endif /* __APPLE__ */
686
687#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000688
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000689#ifdef HAVE_EPOLL
690/* **************************************************************************
691 * epoll interface for Linux 2.6
692 *
693 * Written by Christian Heimes
694 * Inspired by Twisted's _epoll.pyx and select.poll()
695 */
696
697#ifdef HAVE_SYS_EPOLL_H
698#include <sys/epoll.h>
699#endif
700
701typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000702 PyObject_HEAD
703 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000704} pyEpoll_Object;
705
706static PyTypeObject pyEpoll_Type;
707#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
708
709static PyObject *
710pyepoll_err_closed(void)
711{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000712 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
713 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000714}
715
716static int
717pyepoll_internal_close(pyEpoll_Object *self)
718{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000719 int save_errno = 0;
720 if (self->epfd >= 0) {
721 int epfd = self->epfd;
722 self->epfd = -1;
723 Py_BEGIN_ALLOW_THREADS
724 if (close(epfd) < 0)
725 save_errno = errno;
726 Py_END_ALLOW_THREADS
727 }
728 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000729}
730
731static PyObject *
732newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
733{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000734 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000735
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000736 if (sizehint == -1) {
737 sizehint = FD_SETSIZE-1;
738 }
739 else if (sizehint < 1) {
740 PyErr_Format(PyExc_ValueError,
741 "sizehint must be greater zero, got %d",
742 sizehint);
743 return NULL;
744 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000745
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000746 assert(type != NULL && type->tp_alloc != NULL);
747 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
748 if (self == NULL)
749 return NULL;
750
751 if (fd == -1) {
752 Py_BEGIN_ALLOW_THREADS
753 self->epfd = epoll_create(sizehint);
754 Py_END_ALLOW_THREADS
755 }
756 else {
757 self->epfd = fd;
758 }
759 if (self->epfd < 0) {
760 Py_DECREF(self);
761 PyErr_SetFromErrno(PyExc_IOError);
762 return NULL;
763 }
764 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000765}
766
767
768static PyObject *
769pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
770{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000771 int sizehint = -1;
772 static char *kwlist[] = {"sizehint", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000773
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000774 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:epoll", kwlist,
775 &sizehint))
776 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000777
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000778 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000779}
780
781
782static void
783pyepoll_dealloc(pyEpoll_Object *self)
784{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000785 (void)pyepoll_internal_close(self);
786 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000787}
788
789static PyObject*
790pyepoll_close(pyEpoll_Object *self)
791{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000792 errno = pyepoll_internal_close(self);
793 if (errno < 0) {
794 PyErr_SetFromErrno(PyExc_IOError);
795 return NULL;
796 }
797 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000798}
799
800PyDoc_STRVAR(pyepoll_close_doc,
801"close() -> None\n\
802\n\
803Close the epoll control file descriptor. Further operations on the epoll\n\
804object will raise an exception.");
805
806static PyObject*
807pyepoll_get_closed(pyEpoll_Object *self)
808{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000809 if (self->epfd < 0)
810 Py_RETURN_TRUE;
811 else
812 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000813}
814
815static PyObject*
816pyepoll_fileno(pyEpoll_Object *self)
817{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000818 if (self->epfd < 0)
819 return pyepoll_err_closed();
820 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000821}
822
823PyDoc_STRVAR(pyepoll_fileno_doc,
824"fileno() -> int\n\
825\n\
826Return the epoll control file descriptor.");
827
828static PyObject*
829pyepoll_fromfd(PyObject *cls, PyObject *args)
830{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000831 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000832
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000833 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
834 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000835
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000836 return newPyEpoll_Object((PyTypeObject*)cls, -1, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000837}
838
839PyDoc_STRVAR(pyepoll_fromfd_doc,
840"fromfd(fd) -> epoll\n\
841\n\
842Create an epoll object from a given control fd.");
843
844static PyObject *
845pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
846{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000847 struct epoll_event ev;
848 int result;
849 int fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000850
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000851 if (epfd < 0)
852 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000853
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000854 fd = PyObject_AsFileDescriptor(pfd);
855 if (fd == -1) {
856 return NULL;
857 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000858
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000859 switch(op) {
860 case EPOLL_CTL_ADD:
861 case EPOLL_CTL_MOD:
862 ev.events = events;
863 ev.data.fd = fd;
864 Py_BEGIN_ALLOW_THREADS
865 result = epoll_ctl(epfd, op, fd, &ev);
866 Py_END_ALLOW_THREADS
867 break;
868 case EPOLL_CTL_DEL:
869 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
870 * operation required a non-NULL pointer in event, even
871 * though this argument is ignored. */
872 Py_BEGIN_ALLOW_THREADS
873 result = epoll_ctl(epfd, op, fd, &ev);
874 if (errno == EBADF) {
875 /* fd already closed */
876 result = 0;
877 errno = 0;
878 }
879 Py_END_ALLOW_THREADS
880 break;
881 default:
882 result = -1;
883 errno = EINVAL;
884 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000885
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000886 if (result < 0) {
887 PyErr_SetFromErrno(PyExc_IOError);
888 return NULL;
889 }
890 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000891}
892
893static PyObject *
894pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
895{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000896 PyObject *pfd;
897 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
898 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000899
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000900 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
901 &pfd, &events)) {
902 return NULL;
903 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000904
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000905 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000906}
907
908PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl222569d2010-08-02 20:47:56 +0000909"register(fd[, eventmask]) -> None\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000910\n\
Senthil Kumaran7d80bd12011-06-26 23:48:23 -0700911Registers a new fd or raises an IOError if the fd is already registered.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000912fd is the target file descriptor of the operation.\n\
913events is a bit set composed of the various EPOLL constants; the default\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000914is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
915\n\
916The epoll interface supports all file descriptors that support poll.");
917
918static PyObject *
919pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
920{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000921 PyObject *pfd;
922 unsigned int events;
923 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000924
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000925 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
926 &pfd, &events)) {
927 return NULL;
928 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000929
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000930 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000931}
932
933PyDoc_STRVAR(pyepoll_modify_doc,
934"modify(fd, eventmask) -> None\n\
935\n\
936fd is the target file descriptor of the operation\n\
937events is a bit set composed of the various EPOLL constants");
938
939static PyObject *
940pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
941{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000942 PyObject *pfd;
943 static char *kwlist[] = {"fd", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000944
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000945 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
946 &pfd)) {
947 return NULL;
948 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000949
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000950 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000951}
952
953PyDoc_STRVAR(pyepoll_unregister_doc,
954"unregister(fd) -> None\n\
955\n\
956fd is the target file descriptor of the operation.");
957
958static PyObject *
959pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
960{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000961 double dtimeout = -1.;
962 int timeout;
963 int maxevents = -1;
964 int nfds, i;
965 PyObject *elist = NULL, *etuple = NULL;
966 struct epoll_event *evs = NULL;
967 static char *kwlist[] = {"timeout", "maxevents", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000968
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000969 if (self->epfd < 0)
970 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000971
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000972 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
973 &dtimeout, &maxevents)) {
974 return NULL;
975 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000976
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000977 if (dtimeout < 0) {
978 timeout = -1;
979 }
980 else if (dtimeout * 1000.0 > INT_MAX) {
981 PyErr_SetString(PyExc_OverflowError,
982 "timeout is too large");
983 return NULL;
984 }
985 else {
986 timeout = (int)(dtimeout * 1000.0);
987 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000988
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000989 if (maxevents == -1) {
990 maxevents = FD_SETSIZE-1;
991 }
992 else if (maxevents < 1) {
993 PyErr_Format(PyExc_ValueError,
994 "maxevents must be greater than 0, got %d",
995 maxevents);
996 return NULL;
997 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000998
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000999 evs = PyMem_New(struct epoll_event, maxevents);
1000 if (evs == NULL) {
1001 Py_DECREF(self);
1002 PyErr_NoMemory();
1003 return NULL;
1004 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001005
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 Py_BEGIN_ALLOW_THREADS
1007 nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
1008 Py_END_ALLOW_THREADS
1009 if (nfds < 0) {
1010 PyErr_SetFromErrno(PyExc_IOError);
1011 goto error;
1012 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014 elist = PyList_New(nfds);
1015 if (elist == NULL) {
1016 goto error;
1017 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001018
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001019 for (i = 0; i < nfds; i++) {
1020 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
1021 if (etuple == NULL) {
1022 Py_CLEAR(elist);
1023 goto error;
1024 }
1025 PyList_SET_ITEM(elist, i, etuple);
1026 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001027
Christian Heimesf6cd9672008-03-26 13:45:42 +00001028 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001029 PyMem_Free(evs);
1030 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001031}
1032
1033PyDoc_STRVAR(pyepoll_poll_doc,
1034"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1035\n\
1036Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1037in seconds (as float). -1 makes poll wait indefinitely.\n\
1038Up to maxevents are returned to the caller.");
1039
1040static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001041 {"fromfd", (PyCFunction)pyepoll_fromfd,
1042 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1043 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1044 pyepoll_close_doc},
1045 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1046 pyepoll_fileno_doc},
1047 {"modify", (PyCFunction)pyepoll_modify,
1048 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1049 {"register", (PyCFunction)pyepoll_register,
1050 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1051 {"unregister", (PyCFunction)pyepoll_unregister,
1052 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1053 {"poll", (PyCFunction)pyepoll_poll,
1054 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
1055 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001056};
1057
1058static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001059 {"closed", (getter)pyepoll_get_closed, NULL,
1060 "True if the epoll handler is closed"},
1061 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001062};
1063
1064PyDoc_STRVAR(pyepoll_doc,
1065"select.epoll([sizehint=-1])\n\
1066\n\
1067Returns an epolling object\n\
1068\n\
1069sizehint must be a positive integer or -1 for the default size. The\n\
1070sizehint is used to optimize internal data structures. It doesn't limit\n\
1071the maximum number of monitored events.");
1072
1073static PyTypeObject pyEpoll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001074 PyVarObject_HEAD_INIT(NULL, 0)
1075 "select.epoll", /* tp_name */
1076 sizeof(pyEpoll_Object), /* tp_basicsize */
1077 0, /* tp_itemsize */
1078 (destructor)pyepoll_dealloc, /* tp_dealloc */
1079 0, /* tp_print */
1080 0, /* tp_getattr */
1081 0, /* tp_setattr */
1082 0, /* tp_reserved */
1083 0, /* tp_repr */
1084 0, /* tp_as_number */
1085 0, /* tp_as_sequence */
1086 0, /* tp_as_mapping */
1087 0, /* tp_hash */
1088 0, /* tp_call */
1089 0, /* tp_str */
1090 PyObject_GenericGetAttr, /* tp_getattro */
1091 0, /* tp_setattro */
1092 0, /* tp_as_buffer */
1093 Py_TPFLAGS_DEFAULT, /* tp_flags */
1094 pyepoll_doc, /* tp_doc */
1095 0, /* tp_traverse */
1096 0, /* tp_clear */
1097 0, /* tp_richcompare */
1098 0, /* tp_weaklistoffset */
1099 0, /* tp_iter */
1100 0, /* tp_iternext */
1101 pyepoll_methods, /* tp_methods */
1102 0, /* tp_members */
1103 pyepoll_getsetlist, /* tp_getset */
1104 0, /* tp_base */
1105 0, /* tp_dict */
1106 0, /* tp_descr_get */
1107 0, /* tp_descr_set */
1108 0, /* tp_dictoffset */
1109 0, /* tp_init */
1110 0, /* tp_alloc */
1111 pyepoll_new, /* tp_new */
1112 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001113};
1114
1115#endif /* HAVE_EPOLL */
1116
1117#ifdef HAVE_KQUEUE
1118/* **************************************************************************
1119 * kqueue interface for BSD
1120 *
1121 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1122 * All rights reserved.
1123 *
1124 * Redistribution and use in source and binary forms, with or without
1125 * modification, are permitted provided that the following conditions
1126 * are met:
1127 * 1. Redistributions of source code must retain the above copyright
1128 * notice, this list of conditions and the following disclaimer.
1129 * 2. Redistributions in binary form must reproduce the above copyright
1130 * notice, this list of conditions and the following disclaimer in the
1131 * documentation and/or other materials provided with the distribution.
1132 *
1133 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1134 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1135 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1136 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1137 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1138 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1139 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1140 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1141 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1142 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1143 * SUCH DAMAGE.
1144 */
1145
1146#ifdef HAVE_SYS_EVENT_H
1147#include <sys/event.h>
1148#endif
1149
1150PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001151"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001152\n\
1153This object is the equivalent of the struct kevent for the C API.\n\
1154\n\
1155See the kqueue manpage for more detailed information about the meaning\n\
1156of the arguments.\n\
1157\n\
1158One minor note: while you might hope that udata could store a\n\
1159reference to a python object, it cannot, because it is impossible to\n\
1160keep a proper reference count of the object once it's passed into the\n\
1161kernel. Therefore, I have restricted it to only storing an integer. I\n\
1162recommend ignoring it and simply using the 'ident' field to key off\n\
1163of. You could also set up a dictionary on the python side to store a\n\
1164udata->object mapping.");
1165
1166typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001167 PyObject_HEAD
1168 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001169} kqueue_event_Object;
1170
1171static PyTypeObject kqueue_event_Type;
1172
1173#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1174
1175typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001176 PyObject_HEAD
1177 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001178} kqueue_queue_Object;
1179
1180static PyTypeObject kqueue_queue_Type;
1181
1182#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1183
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001184#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1185# error uintptr_t does not match void *!
1186#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1187# define T_UINTPTRT T_ULONGLONG
1188# define T_INTPTRT T_LONGLONG
1189# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1190# define UINTPTRT_FMT_UNIT "K"
1191# define INTPTRT_FMT_UNIT "L"
1192#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1193# define T_UINTPTRT T_ULONG
1194# define T_INTPTRT T_LONG
1195# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1196# define UINTPTRT_FMT_UNIT "k"
1197# define INTPTRT_FMT_UNIT "l"
1198#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1199# define T_UINTPTRT T_UINT
1200# define T_INTPTRT T_INT
1201# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1202# define UINTPTRT_FMT_UNIT "I"
1203# define INTPTRT_FMT_UNIT "i"
1204#else
1205# error uintptr_t does not match int, long, or long long!
1206#endif
1207
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001208/* Unfortunately, we can't store python objects in udata, because
1209 * kevents in the kernel can be removed without warning, which would
1210 * forever lose the refcount on the object stored with it.
1211 */
1212
1213#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1214static struct PyMemberDef kqueue_event_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001215 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1216 {"filter", T_SHORT, KQ_OFF(e.filter)},
1217 {"flags", T_USHORT, KQ_OFF(e.flags)},
1218 {"fflags", T_UINT, KQ_OFF(e.fflags)},
1219 {"data", T_INTPTRT, KQ_OFF(e.data)},
1220 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1221 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001222};
1223#undef KQ_OFF
1224
1225static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001226
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001227kqueue_event_repr(kqueue_event_Object *s)
1228{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001229 char buf[1024];
1230 PyOS_snprintf(
1231 buf, sizeof(buf),
1232 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1233 "data=0x%zd udata=%p>",
1234 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1235 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1236 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001237}
1238
1239static int
1240kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1241{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001242 PyObject *pfd;
1243 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1244 "data", "udata", NULL};
1245 static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001247 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001248
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001249 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1250 &pfd, &(self->e.filter), &(self->e.flags),
1251 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1252 return -1;
1253 }
1254
1255 if (PyLong_Check(pfd)) {
1256 self->e.ident = PyLong_AsUintptr_t(pfd);
1257 }
1258 else {
1259 self->e.ident = PyObject_AsFileDescriptor(pfd);
1260 }
1261 if (PyErr_Occurred()) {
1262 return -1;
1263 }
1264 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001265}
1266
1267static PyObject *
1268kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001269 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001270{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001271 Py_intptr_t result = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001273 if (!kqueue_event_Check(o)) {
1274 if (op == Py_EQ || op == Py_NE) {
1275 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1276 Py_INCREF(res);
1277 return res;
1278 }
1279 PyErr_Format(PyExc_TypeError,
1280 "can't compare %.200s to %.200s",
1281 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1282 return NULL;
1283 }
1284 if (((result = s->e.ident - o->e.ident) == 0) &&
1285 ((result = s->e.filter - o->e.filter) == 0) &&
1286 ((result = s->e.flags - o->e.flags) == 0) &&
1287 ((result = s->e.fflags - o->e.fflags) == 0) &&
1288 ((result = s->e.data - o->e.data) == 0) &&
1289 ((result = s->e.udata - o->e.udata) == 0)
1290 ) {
1291 result = 0;
1292 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001293
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001294 switch (op) {
1295 case Py_EQ:
1296 result = (result == 0);
1297 break;
1298 case Py_NE:
1299 result = (result != 0);
1300 break;
1301 case Py_LE:
1302 result = (result <= 0);
1303 break;
1304 case Py_GE:
1305 result = (result >= 0);
1306 break;
1307 case Py_LT:
1308 result = (result < 0);
1309 break;
1310 case Py_GT:
1311 result = (result > 0);
1312 break;
1313 }
1314 return PyBool_FromLong((long)result);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001315}
1316
1317static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 PyVarObject_HEAD_INIT(NULL, 0)
1319 "select.kevent", /* tp_name */
1320 sizeof(kqueue_event_Object), /* tp_basicsize */
1321 0, /* tp_itemsize */
1322 0, /* tp_dealloc */
1323 0, /* tp_print */
1324 0, /* tp_getattr */
1325 0, /* tp_setattr */
1326 0, /* tp_reserved */
1327 (reprfunc)kqueue_event_repr, /* tp_repr */
1328 0, /* tp_as_number */
1329 0, /* tp_as_sequence */
1330 0, /* tp_as_mapping */
1331 0, /* tp_hash */
1332 0, /* tp_call */
1333 0, /* tp_str */
1334 0, /* tp_getattro */
1335 0, /* tp_setattro */
1336 0, /* tp_as_buffer */
1337 Py_TPFLAGS_DEFAULT, /* tp_flags */
1338 kqueue_event_doc, /* tp_doc */
1339 0, /* tp_traverse */
1340 0, /* tp_clear */
1341 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1342 0, /* tp_weaklistoffset */
1343 0, /* tp_iter */
1344 0, /* tp_iternext */
1345 0, /* tp_methods */
1346 kqueue_event_members, /* tp_members */
1347 0, /* tp_getset */
1348 0, /* tp_base */
1349 0, /* tp_dict */
1350 0, /* tp_descr_get */
1351 0, /* tp_descr_set */
1352 0, /* tp_dictoffset */
1353 (initproc)kqueue_event_init, /* tp_init */
1354 0, /* tp_alloc */
1355 0, /* tp_new */
1356 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001357};
1358
1359static PyObject *
1360kqueue_queue_err_closed(void)
1361{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001362 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1363 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001364}
1365
1366static int
1367kqueue_queue_internal_close(kqueue_queue_Object *self)
1368{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001369 int save_errno = 0;
1370 if (self->kqfd >= 0) {
1371 int kqfd = self->kqfd;
1372 self->kqfd = -1;
1373 Py_BEGIN_ALLOW_THREADS
1374 if (close(kqfd) < 0)
1375 save_errno = errno;
1376 Py_END_ALLOW_THREADS
1377 }
1378 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001379}
1380
1381static PyObject *
1382newKqueue_Object(PyTypeObject *type, SOCKET fd)
1383{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001384 kqueue_queue_Object *self;
1385 assert(type != NULL && type->tp_alloc != NULL);
1386 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1387 if (self == NULL) {
1388 return NULL;
1389 }
1390
1391 if (fd == -1) {
1392 Py_BEGIN_ALLOW_THREADS
1393 self->kqfd = kqueue();
1394 Py_END_ALLOW_THREADS
1395 }
1396 else {
1397 self->kqfd = fd;
1398 }
1399 if (self->kqfd < 0) {
1400 Py_DECREF(self);
1401 PyErr_SetFromErrno(PyExc_IOError);
1402 return NULL;
1403 }
1404 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001405}
1406
1407static PyObject *
1408kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1409{
1410
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001411 if ((args != NULL && PyObject_Size(args)) ||
1412 (kwds != NULL && PyObject_Size(kwds))) {
1413 PyErr_SetString(PyExc_ValueError,
1414 "select.kqueue doesn't accept arguments");
1415 return NULL;
1416 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001417
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001418 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001419}
1420
1421static void
1422kqueue_queue_dealloc(kqueue_queue_Object *self)
1423{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001424 kqueue_queue_internal_close(self);
1425 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001426}
1427
1428static PyObject*
1429kqueue_queue_close(kqueue_queue_Object *self)
1430{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001431 errno = kqueue_queue_internal_close(self);
1432 if (errno < 0) {
1433 PyErr_SetFromErrno(PyExc_IOError);
1434 return NULL;
1435 }
1436 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001437}
1438
1439PyDoc_STRVAR(kqueue_queue_close_doc,
1440"close() -> None\n\
1441\n\
1442Close the kqueue control file descriptor. Further operations on the kqueue\n\
1443object will raise an exception.");
1444
1445static PyObject*
1446kqueue_queue_get_closed(kqueue_queue_Object *self)
1447{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001448 if (self->kqfd < 0)
1449 Py_RETURN_TRUE;
1450 else
1451 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001452}
1453
1454static PyObject*
1455kqueue_queue_fileno(kqueue_queue_Object *self)
1456{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001457 if (self->kqfd < 0)
1458 return kqueue_queue_err_closed();
1459 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001460}
1461
1462PyDoc_STRVAR(kqueue_queue_fileno_doc,
1463"fileno() -> int\n\
1464\n\
1465Return the kqueue control file descriptor.");
1466
1467static PyObject*
1468kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1469{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001470 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001471
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001472 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1473 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001474
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001475 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001476}
1477
1478PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1479"fromfd(fd) -> kqueue\n\
1480\n\
1481Create a kqueue object from a given control fd.");
1482
1483static PyObject *
1484kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1485{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001486 int nevents = 0;
1487 int gotevents = 0;
1488 int nchanges = 0;
1489 int i = 0;
1490 PyObject *otimeout = NULL;
1491 PyObject *ch = NULL;
1492 PyObject *it = NULL, *ei = NULL;
1493 PyObject *result = NULL;
1494 struct kevent *evl = NULL;
1495 struct kevent *chl = NULL;
1496 struct timespec timeoutspec;
1497 struct timespec *ptimeoutspec;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001499 if (self->kqfd < 0)
1500 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001501
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001502 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1503 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001505 if (nevents < 0) {
1506 PyErr_Format(PyExc_ValueError,
1507 "Length of eventlist must be 0 or positive, got %d",
1508 nevents);
1509 return NULL;
1510 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001512 if (otimeout == Py_None || otimeout == NULL) {
1513 ptimeoutspec = NULL;
1514 }
1515 else if (PyNumber_Check(otimeout)) {
1516 double timeout;
1517 long seconds;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001518
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001519 timeout = PyFloat_AsDouble(otimeout);
1520 if (timeout == -1 && PyErr_Occurred())
1521 return NULL;
1522 if (timeout > (double)LONG_MAX) {
1523 PyErr_SetString(PyExc_OverflowError,
1524 "timeout period too long");
1525 return NULL;
1526 }
1527 if (timeout < 0) {
1528 PyErr_SetString(PyExc_ValueError,
1529 "timeout must be positive or None");
1530 return NULL;
1531 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001532
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001533 seconds = (long)timeout;
1534 timeout = timeout - (double)seconds;
1535 timeoutspec.tv_sec = seconds;
1536 timeoutspec.tv_nsec = (long)(timeout * 1E9);
1537 ptimeoutspec = &timeoutspec;
1538 }
1539 else {
1540 PyErr_Format(PyExc_TypeError,
1541 "timeout argument must be an number "
1542 "or None, got %.200s",
1543 Py_TYPE(otimeout)->tp_name);
1544 return NULL;
1545 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001546
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001547 if (ch != NULL && ch != Py_None) {
1548 it = PyObject_GetIter(ch);
1549 if (it == NULL) {
1550 PyErr_SetString(PyExc_TypeError,
1551 "changelist is not iterable");
1552 return NULL;
1553 }
1554 nchanges = PyObject_Size(ch);
1555 if (nchanges < 0) {
1556 goto error;
1557 }
Georg Brandlc0e22b72010-03-14 10:51:01 +00001558
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001559 chl = PyMem_New(struct kevent, nchanges);
1560 if (chl == NULL) {
1561 PyErr_NoMemory();
1562 goto error;
1563 }
1564 i = 0;
1565 while ((ei = PyIter_Next(it)) != NULL) {
1566 if (!kqueue_event_Check(ei)) {
1567 Py_DECREF(ei);
1568 PyErr_SetString(PyExc_TypeError,
1569 "changelist must be an iterable of "
1570 "select.kevent objects");
1571 goto error;
1572 } else {
1573 chl[i++] = ((kqueue_event_Object *)ei)->e;
1574 }
1575 Py_DECREF(ei);
1576 }
1577 }
1578 Py_CLEAR(it);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001579
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001580 /* event list */
1581 if (nevents) {
1582 evl = PyMem_New(struct kevent, nevents);
1583 if (evl == NULL) {
1584 PyErr_NoMemory();
1585 goto error;
1586 }
1587 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001588
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001589 Py_BEGIN_ALLOW_THREADS
1590 gotevents = kevent(self->kqfd, chl, nchanges,
1591 evl, nevents, ptimeoutspec);
1592 Py_END_ALLOW_THREADS
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001593
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001594 if (gotevents == -1) {
1595 PyErr_SetFromErrno(PyExc_OSError);
1596 goto error;
1597 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001598
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001599 result = PyList_New(gotevents);
1600 if (result == NULL) {
1601 goto error;
1602 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001603
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001604 for (i = 0; i < gotevents; i++) {
1605 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001606
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001607 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1608 if (ch == NULL) {
1609 goto error;
1610 }
1611 ch->e = evl[i];
1612 PyList_SET_ITEM(result, i, (PyObject *)ch);
1613 }
1614 PyMem_Free(chl);
1615 PyMem_Free(evl);
1616 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001617
1618 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001619 PyMem_Free(chl);
1620 PyMem_Free(evl);
1621 Py_XDECREF(result);
1622 Py_XDECREF(it);
1623 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001624}
1625
1626PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00001627"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001628\n\
1629Calls the kernel kevent function.\n\
1630- changelist must be a list of kevent objects describing the changes\n\
1631 to be made to the kernel's watch list or None.\n\
1632- max_events lets you specify the maximum number of events that the\n\
1633 kernel will return.\n\
1634- timeout is the maximum time to wait in seconds, or else None,\n\
1635 to wait forever. timeout accepts floats for smaller timeouts, too.");
1636
1637
1638static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001639 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
1640 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
1641 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
1642 kqueue_queue_close_doc},
1643 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
1644 kqueue_queue_fileno_doc},
1645 {"control", (PyCFunction)kqueue_queue_control,
1646 METH_VARARGS , kqueue_queue_control_doc},
1647 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001648};
1649
1650static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001651 {"closed", (getter)kqueue_queue_get_closed, NULL,
1652 "True if the kqueue handler is closed"},
1653 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001654};
1655
1656PyDoc_STRVAR(kqueue_queue_doc,
1657"Kqueue syscall wrapper.\n\
1658\n\
1659For example, to start watching a socket for input:\n\
1660>>> kq = kqueue()\n\
1661>>> sock = socket()\n\
1662>>> sock.connect((host, port))\n\
1663>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
1664\n\
1665To wait one second for it to become writeable:\n\
1666>>> kq.control(None, 1, 1000)\n\
1667\n\
1668To stop listening:\n\
1669>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
1670
1671static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001672 PyVarObject_HEAD_INIT(NULL, 0)
1673 "select.kqueue", /* tp_name */
1674 sizeof(kqueue_queue_Object), /* tp_basicsize */
1675 0, /* tp_itemsize */
1676 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
1677 0, /* tp_print */
1678 0, /* tp_getattr */
1679 0, /* tp_setattr */
1680 0, /* tp_reserved */
1681 0, /* tp_repr */
1682 0, /* tp_as_number */
1683 0, /* tp_as_sequence */
1684 0, /* tp_as_mapping */
1685 0, /* tp_hash */
1686 0, /* tp_call */
1687 0, /* tp_str */
1688 0, /* tp_getattro */
1689 0, /* tp_setattro */
1690 0, /* tp_as_buffer */
1691 Py_TPFLAGS_DEFAULT, /* tp_flags */
1692 kqueue_queue_doc, /* tp_doc */
1693 0, /* tp_traverse */
1694 0, /* tp_clear */
1695 0, /* tp_richcompare */
1696 0, /* tp_weaklistoffset */
1697 0, /* tp_iter */
1698 0, /* tp_iternext */
1699 kqueue_queue_methods, /* tp_methods */
1700 0, /* tp_members */
1701 kqueue_queue_getsetlist, /* tp_getset */
1702 0, /* tp_base */
1703 0, /* tp_dict */
1704 0, /* tp_descr_get */
1705 0, /* tp_descr_set */
1706 0, /* tp_dictoffset */
1707 0, /* tp_init */
1708 0, /* tp_alloc */
1709 kqueue_queue_new, /* tp_new */
1710 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001711};
1712
1713#endif /* HAVE_KQUEUE */
1714/* ************************************************************************ */
1715
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001716PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001717"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
1718\n\
1719Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00001720The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001721rlist -- wait until ready for reading\n\
1722wlist -- wait until ready for writing\n\
1723xlist -- wait for an ``exceptional condition''\n\
1724If only one kind of condition is required, pass [] for the other lists.\n\
1725A file descriptor is either a socket or file object, or a small integer\n\
1726gotten from a fileno() method call on one of those.\n\
1727\n\
1728The optional 4th argument specifies a timeout in seconds; it may be\n\
1729a floating point number to specify fractions of seconds. If it is absent\n\
1730or None, the call will never time out.\n\
1731\n\
1732The return value is a tuple of three lists corresponding to the first three\n\
1733arguments; each contains the subset of the corresponding file descriptors\n\
1734that are ready.\n\
1735\n\
1736*** IMPORTANT NOTICE ***\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001737On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001738descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001739
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00001740static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001741 {"select", select_select, METH_VARARGS, select_doc},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001742#ifdef HAVE_POLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001743 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00001744#endif /* HAVE_POLL */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001745 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00001746};
1747
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001748PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001749"This module supports asynchronous I/O on multiple file descriptors.\n\
1750\n\
1751*** IMPORTANT NOTICE ***\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001752On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00001753
Martin v. Löwis1a214512008-06-11 05:26:20 +00001754
1755static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001756 PyModuleDef_HEAD_INIT,
1757 "select",
1758 module_doc,
1759 -1,
1760 select_methods,
1761 NULL,
1762 NULL,
1763 NULL,
1764 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001765};
1766
Mark Hammond62b1ab12002-07-23 06:31:15 +00001767PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001768PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00001769{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001770 PyObject *m;
1771 m = PyModule_Create(&selectmodule);
1772 if (m == NULL)
1773 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00001774
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001775 SelectError = PyErr_NewException("select.error", NULL, NULL);
1776 Py_INCREF(SelectError);
1777 PyModule_AddObject(m, "error", SelectError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001778
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00001779#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00001780#ifdef HAVE_BROKEN_PIPE_BUF
1781#undef PIPE_BUF
1782#define PIPE_BUF 512
1783#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001784 PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00001785#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00001786
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001787#if defined(HAVE_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001788#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001789 if (select_have_broken_poll()) {
1790 if (PyObject_DelAttrString(m, "poll") == -1) {
1791 PyErr_Clear();
1792 }
1793 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001794#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001795 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001796#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001797 if (PyType_Ready(&poll_Type) < 0)
1798 return NULL;
1799 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
1800 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
1801 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
1802 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
1803 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
1804 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001805
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001806#ifdef POLLRDNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001807 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001808#endif
1809#ifdef POLLRDBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001810 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001811#endif
1812#ifdef POLLWRNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001813 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001814#endif
1815#ifdef POLLWRBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001816 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001817#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001818#ifdef POLLMSG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001819 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001820#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001821 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001822#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001823
1824#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001825 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
1826 if (PyType_Ready(&pyEpoll_Type) < 0)
1827 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001828
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001829 Py_INCREF(&pyEpoll_Type);
1830 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001831
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001832 PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
1833 PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
1834 PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
1835 PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
1836 PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
1837 PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001838#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001839 /* Kernel 2.6.2+ */
1840 PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001841#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001842 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
1843 PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
1844 PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
1845 PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
1846 PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
1847 PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001848#endif /* HAVE_EPOLL */
1849
1850#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001851 kqueue_event_Type.tp_new = PyType_GenericNew;
1852 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
1853 if(PyType_Ready(&kqueue_event_Type) < 0)
1854 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001855
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001856 Py_INCREF(&kqueue_event_Type);
1857 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001858
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001859 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
1860 if(PyType_Ready(&kqueue_queue_Type) < 0)
1861 return NULL;
1862 Py_INCREF(&kqueue_queue_Type);
1863 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
1864
1865 /* event filters */
1866 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
1867 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
1868 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
1869 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
1870 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001871#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001872 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001873#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001874 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
1875 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001876
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001877 /* event flags */
1878 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
1879 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
1880 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
1881 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
1882 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
1883 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001884
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
1886 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001887
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001888 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
1889 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001890
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001891 /* READ WRITE filter flag */
1892 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001893
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001894 /* VNODE filter flags */
1895 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
1896 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
1897 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
1898 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
1899 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
1900 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
1901 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001902
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001903 /* PROC filter flags */
1904 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
1905 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
1906 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
1907 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
1908 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001909
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001910 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
1911 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
1912 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
1913
1914 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001915#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001916 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
1917 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
1918 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001919#endif
1920
1921#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001922 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00001923}