blob: 179dd61856ca0fa676cf04abdcb3832ca0aed740 [file] [log] [blame]
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00001/* select - Module containing unix select(2) call.
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002 Under Unix, the file descriptors are small integers.
3 Under Win32, select only exists for sockets, and sockets may
4 have any value except INVALID_SOCKET.
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00005*/
Guido van Rossumed233a51992-06-23 09:07:03 +00006
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00007#include "Python.h"
Christian Heimes4fbc72b2008-03-22 00:47:35 +00008#include <structmember.h>
Guido van Rossumed233a51992-06-23 09:07:03 +00009
Jesus Cead8b9ae62011-11-14 19:07:41 +010010#ifdef HAVE_SYS_DEVPOLL_H
11#include <sys/resource.h>
12#include <sys/devpoll.h>
13#include <sys/types.h>
14#include <sys/stat.h>
15#include <fcntl.h>
16#endif
17
Thomas Wouters477c8d52006-05-27 19:21:47 +000018#ifdef __APPLE__
19 /* Perform runtime testing for a broken poll on OSX to make it easier
20 * to use the same binary on multiple releases of the OS.
21 */
22#undef HAVE_BROKEN_POLL
23#endif
24
Tim Petersd92dfe02000-12-12 01:18:41 +000025/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
26 64 is too small (too many people have bumped into that limit).
27 Here we boost it.
28 Users who want even more than the boosted limit should #define
29 FD_SETSIZE higher before this; e.g., via compiler /D switch.
30*/
31#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
32#define FD_SETSIZE 512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000033#endif
Tim Petersd92dfe02000-12-12 01:18:41 +000034
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000035#if defined(HAVE_POLL_H)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000036#include <poll.h>
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000037#elif defined(HAVE_SYS_POLL_H)
38#include <sys/poll.h>
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000039#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000040
Guido van Rossum37273171996-12-09 18:47:43 +000041#ifdef __sgi
42/* This is missing from unistd.h */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000043extern void bzero(void *, int);
Guido van Rossum37273171996-12-09 18:47:43 +000044#endif
45
Thomas Wouters0e3f5912006-08-11 14:57:12 +000046#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000047#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000048#endif
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000049
Andrew MacIntyre7bf68332002-03-03 02:59:16 +000050#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000051#include <sys/time.h>
52#include <utils.h>
53#endif
54
Guido van Rossum6f489d91996-06-28 20:15:15 +000055#ifdef MS_WINDOWS
Christian Heimesc36625b2008-01-04 13:33:00 +000056# define WIN32_LEAN_AND_MEAN
Thomas Wouters0e3f5912006-08-11 14:57:12 +000057# include <winsock.h>
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000058#else
Thomas Wouters0e3f5912006-08-11 14:57:12 +000059# define SOCKET int
Skip Montanaroeb33e5a2007-08-17 12:57:41 +000060# if defined(__VMS)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000061# include <socket.h>
62# endif
Guido van Rossumbcc20741998-08-04 22:53:56 +000063#endif
Guido van Rossumed233a51992-06-23 09:07:03 +000064
Barry Warsawc1cb3601996-12-12 22:16:21 +000065/* list of Python objects and their file descriptor */
66typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000067 PyObject *obj; /* owned reference */
68 SOCKET fd;
69 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000070} pylist;
71
Barry Warsawc1cb3601996-12-12 22:16:21 +000072static void
Tim Peters4b046c22001-08-16 21:59:46 +000073reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +000074{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000075 int i;
76 for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
77 Py_XDECREF(fd2obj[i].obj);
78 fd2obj[i].obj = NULL;
79 }
80 fd2obj[0].sentinel = -1;
Barry Warsawc1cb3601996-12-12 22:16:21 +000081}
82
83
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000084/* returns -1 and sets the Python exception if an error occurred, otherwise
85 returns a number >= 0
86*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000087static int
Brett Cannon62dba4c2003-09-10 19:37:42 +000088seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +000089{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000090 int max = -1;
91 int index = 0;
Victor Stinner0fcab4a2011-01-04 12:59:15 +000092 Py_ssize_t i, len = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000093 PyObject* fast_seq = NULL;
94 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000095
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000096 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
97 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000098
Benjamin Petersone0edb8b2010-06-27 23:49:45 +000099 fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000100 if (!fast_seq)
101 return -1;
102
103 len = PySequence_Fast_GET_SIZE(fast_seq);
104
105 for (i = 0; i < len; i++) {
106 SOCKET v;
107
108 /* any intervening fileno() calls could decr this refcnt */
109 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Brett Cannon62dba4c2003-09-10 19:37:42 +0000110 return -1;
111
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000112 Py_INCREF(o);
113 v = PyObject_AsFileDescriptor( o );
114 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000115
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000116#if defined(_MSC_VER)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000117 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000118#else /* !_MSC_VER */
Charles-François Nataliaa26b272011-08-28 17:51:43 +0200119 if (!_PyIsSelectable_fd(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000120 PyErr_SetString(PyExc_ValueError,
121 "filedescriptor out of range in select()");
122 goto finally;
123 }
124 if (v > max)
125 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000126#endif /* _MSC_VER */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000127 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000128
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000129 /* add object and its file descriptor to the list */
130 if (index >= FD_SETSIZE) {
131 PyErr_SetString(PyExc_ValueError,
132 "too many file descriptors in select()");
133 goto finally;
134 }
135 fd2obj[index].obj = o;
136 fd2obj[index].fd = v;
137 fd2obj[index].sentinel = 0;
138 fd2obj[++index].sentinel = -1;
139 }
140 Py_DECREF(fast_seq);
141 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000142
143 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000144 Py_XDECREF(o);
145 Py_DECREF(fast_seq);
146 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000147}
148
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000149/* returns NULL and sets the Python exception if an error occurred */
150static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000151set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000152{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000153 int i, j, count=0;
154 PyObject *list, *o;
155 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000156
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000157 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
158 if (FD_ISSET(fd2obj[j].fd, set))
159 count++;
160 }
161 list = PyList_New(count);
162 if (!list)
163 return NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000165 i = 0;
166 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
167 fd = fd2obj[j].fd;
168 if (FD_ISSET(fd, set)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000169 o = fd2obj[j].obj;
170 fd2obj[j].obj = NULL;
171 /* transfer ownership */
172 if (PyList_SetItem(list, i, o) < 0)
173 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000174
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000175 i++;
176 }
177 }
178 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000179 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000180 Py_DECREF(list);
181 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000182}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000183
Barry Warsawb44740f2001-08-16 16:52:59 +0000184#undef SELECT_USES_HEAP
185#if FD_SETSIZE > 1024
186#define SELECT_USES_HEAP
187#endif /* FD_SETSIZE > 1024 */
188
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000189static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000190select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000191{
Barry Warsawb44740f2001-08-16 16:52:59 +0000192#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000193 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000194#else /* !SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000195 /* XXX: All this should probably be implemented as follows:
196 * - find the highest descriptor we're interested in
197 * - add one
198 * - that's the size
199 * See: Stevens, APitUE, $12.5.1
200 */
201 pylist rfd2obj[FD_SETSIZE + 1];
202 pylist wfd2obj[FD_SETSIZE + 1];
203 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000204#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000205 PyObject *ifdlist, *ofdlist, *efdlist;
206 PyObject *ret = NULL;
207 PyObject *tout = Py_None;
208 fd_set ifdset, ofdset, efdset;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000209 struct timeval tv, *tvp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000210 int imax, omax, emax, max;
211 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000212
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000213 /* convert arguments */
214 if (!PyArg_UnpackTuple(args, "select", 3, 4,
215 &ifdlist, &ofdlist, &efdlist, &tout))
216 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000217
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000218 if (tout == Py_None)
219 tvp = (struct timeval *)0;
220 else if (!PyNumber_Check(tout)) {
221 PyErr_SetString(PyExc_TypeError,
222 "timeout must be a float or None");
223 return NULL;
224 }
225 else {
Victor Stinnerd327f9d2012-03-13 15:29:08 +0100226 long usec;
227 if (_PyTime_ObjectToTimeval(tout, &tv.tv_sec, &usec) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000228 return NULL;
Victor Stinnerd327f9d2012-03-13 15:29:08 +0100229 tv.tv_usec = usec;
Victor Stinner5d272cc2012-03-13 13:35:55 +0100230 if (tv.tv_sec < 0) {
231 PyErr_SetString(PyExc_ValueError, "timeout must be non-negative");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000232 return NULL;
233 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000234 tvp = &tv;
235 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000236
Guido van Rossumed233a51992-06-23 09:07:03 +0000237
Barry Warsawb44740f2001-08-16 16:52:59 +0000238#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000239 /* Allocate memory for the lists */
240 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
241 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
242 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
243 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
244 if (rfd2obj) PyMem_DEL(rfd2obj);
245 if (wfd2obj) PyMem_DEL(wfd2obj);
246 if (efd2obj) PyMem_DEL(efd2obj);
247 return PyErr_NoMemory();
248 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000249#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000250 /* Convert sequences to fd_sets, and get maximum fd number
251 * propagates the Python exception set in seq2set()
252 */
253 rfd2obj[0].sentinel = -1;
254 wfd2obj[0].sentinel = -1;
255 efd2obj[0].sentinel = -1;
256 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
257 goto finally;
258 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
259 goto finally;
260 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
261 goto finally;
262 max = imax;
263 if (omax > max) max = omax;
264 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000265
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000266 Py_BEGIN_ALLOW_THREADS
267 n = select(max, &ifdset, &ofdset, &efdset, tvp);
268 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000269
Thomas Heller106f4c72002-09-24 16:51:00 +0000270#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000271 if (n == SOCKET_ERROR) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200272 PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000273 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000274#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000275 if (n < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200276 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000277 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000278#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000279 else {
280 /* any of these three calls can raise an exception. it's more
281 convenient to test for this after all three calls... but
282 is that acceptable?
283 */
284 ifdlist = set2list(&ifdset, rfd2obj);
285 ofdlist = set2list(&ofdset, wfd2obj);
286 efdlist = set2list(&efdset, efd2obj);
287 if (PyErr_Occurred())
288 ret = NULL;
289 else
290 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000291
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000292 Py_DECREF(ifdlist);
293 Py_DECREF(ofdlist);
294 Py_DECREF(efdlist);
295 }
296
Barry Warsawc1cb3601996-12-12 22:16:21 +0000297 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000298 reap_obj(rfd2obj);
299 reap_obj(wfd2obj);
300 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000301#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000302 PyMem_DEL(rfd2obj);
303 PyMem_DEL(wfd2obj);
304 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000305#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000307}
308
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000309#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000310/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000311 * poll() support
312 */
313
314typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000315 PyObject_HEAD
316 PyObject *dict;
317 int ufd_uptodate;
318 int ufd_len;
319 struct pollfd *ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000320} pollObject;
321
Jeremy Hylton938ace62002-07-17 16:30:39 +0000322static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000324/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000325 contained within a pollObject. Return 1 on success, 0 on an error.
326*/
327
328static int
329update_ufd_array(pollObject *self)
330{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000331 Py_ssize_t i, pos;
332 PyObject *key, *value;
333 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000335 self->ufd_len = PyDict_Size(self->dict);
336 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
337 if (self->ufds == NULL) {
338 self->ufds = old_ufds;
339 PyErr_NoMemory();
340 return 0;
341 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000342
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000343 i = pos = 0;
344 while (PyDict_Next(self->dict, &pos, &key, &value)) {
345 self->ufds[i].fd = PyLong_AsLong(key);
346 self->ufds[i].events = (short)PyLong_AsLong(value);
347 i++;
348 }
349 self->ufd_uptodate = 1;
350 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000351}
352
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000353PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000354"register(fd [, eventmask] ) -> None\n\n\
355Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000356fd -- either an integer, or an object with a fileno() method returning an\n\
357 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000358events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000359
360static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000361poll_register(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000362{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000363 PyObject *o, *key, *value;
364 int fd, events = POLLIN | POLLPRI | POLLOUT;
365 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000366
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000367 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
368 return NULL;
369 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000370
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000371 fd = PyObject_AsFileDescriptor(o);
372 if (fd == -1) return NULL;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000373
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 /* Add entry to the internal dictionary: the key is the
375 file descriptor, and the value is the event mask. */
376 key = PyLong_FromLong(fd);
377 if (key == NULL)
378 return NULL;
379 value = PyLong_FromLong(events);
380 if (value == NULL) {
381 Py_DECREF(key);
382 return NULL;
383 }
384 err = PyDict_SetItem(self->dict, key, value);
385 Py_DECREF(key);
386 Py_DECREF(value);
387 if (err < 0)
388 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000389
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000390 self->ufd_uptodate = 0;
391
392 Py_INCREF(Py_None);
393 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000394}
395
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000396PyDoc_STRVAR(poll_modify_doc,
397"modify(fd, eventmask) -> None\n\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000398Modify an already registered file descriptor.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000399fd -- either an integer, or an object with a fileno() method returning an\n\
400 int.\n\
401events -- an optional bitmask describing the type of events to check for");
402
403static PyObject *
404poll_modify(pollObject *self, PyObject *args)
405{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000406 PyObject *o, *key, *value;
407 int fd, events;
408 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000409
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000410 if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) {
411 return NULL;
412 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000413
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000414 fd = PyObject_AsFileDescriptor(o);
415 if (fd == -1) return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000416
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000417 /* Modify registered fd */
418 key = PyLong_FromLong(fd);
419 if (key == NULL)
420 return NULL;
421 if (PyDict_GetItem(self->dict, key) == NULL) {
422 errno = ENOENT;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200423 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000424 return NULL;
425 }
426 value = PyLong_FromLong(events);
427 if (value == NULL) {
428 Py_DECREF(key);
429 return NULL;
430 }
431 err = PyDict_SetItem(self->dict, key, value);
432 Py_DECREF(key);
433 Py_DECREF(value);
434 if (err < 0)
435 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000436
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000437 self->ufd_uptodate = 0;
438
439 Py_INCREF(Py_None);
440 return Py_None;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000441}
442
443
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000444PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000445"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000446Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000447
448static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000449poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000450{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000451 PyObject *key;
452 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000453
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000454 fd = PyObject_AsFileDescriptor( o );
455 if (fd == -1)
456 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000457
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000458 /* Check whether the fd is already in the array */
459 key = PyLong_FromLong(fd);
460 if (key == NULL)
461 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000462
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000463 if (PyDict_DelItem(self->dict, key) == -1) {
464 Py_DECREF(key);
465 /* This will simply raise the KeyError set by PyDict_DelItem
466 if the file descriptor isn't registered. */
467 return NULL;
468 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000470 Py_DECREF(key);
471 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000472
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000473 Py_INCREF(Py_None);
474 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000475}
476
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000477PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000478"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
479Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000480any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000481
482static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000483poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000484{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000485 PyObject *result_list = NULL, *tout = NULL;
486 int timeout = 0, poll_result, i, j;
487 PyObject *value = NULL, *num = NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000488
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000489 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
490 return NULL;
491 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000492
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000493 /* Check values for timeout */
494 if (tout == NULL || tout == Py_None)
495 timeout = -1;
496 else if (!PyNumber_Check(tout)) {
497 PyErr_SetString(PyExc_TypeError,
498 "timeout must be an integer or None");
499 return NULL;
500 }
501 else {
502 tout = PyNumber_Long(tout);
503 if (!tout)
504 return NULL;
505 timeout = PyLong_AsLong(tout);
506 Py_DECREF(tout);
507 if (timeout == -1 && PyErr_Occurred())
508 return NULL;
509 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 /* Ensure the ufd array is up to date */
512 if (!self->ufd_uptodate)
513 if (update_ufd_array(self) == 0)
514 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000515
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000516 /* call poll() */
517 Py_BEGIN_ALLOW_THREADS
518 poll_result = poll(self->ufds, self->ufd_len, timeout);
519 Py_END_ALLOW_THREADS
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000521 if (poll_result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200522 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000523 return NULL;
524 }
525
526 /* build the result list */
527
528 result_list = PyList_New(poll_result);
529 if (!result_list)
530 return NULL;
531 else {
532 for (i = 0, j = 0; j < poll_result; j++) {
533 /* skip to the next fired descriptor */
534 while (!self->ufds[i].revents) {
535 i++;
536 }
537 /* if we hit a NULL return, set value to NULL
538 and break out of loop; code at end will
539 clean up result_list */
540 value = PyTuple_New(2);
541 if (value == NULL)
542 goto error;
543 num = PyLong_FromLong(self->ufds[i].fd);
544 if (num == NULL) {
545 Py_DECREF(value);
546 goto error;
547 }
548 PyTuple_SET_ITEM(value, 0, num);
549
550 /* The &0xffff is a workaround for AIX. 'revents'
551 is a 16-bit short, and IBM assigned POLLNVAL
552 to be 0x8000, so the conversion to int results
553 in a negative number. See SF bug #923315. */
554 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
555 if (num == NULL) {
556 Py_DECREF(value);
557 goto error;
558 }
559 PyTuple_SET_ITEM(value, 1, num);
560 if ((PyList_SetItem(result_list, j, value)) == -1) {
561 Py_DECREF(value);
562 goto error;
563 }
564 i++;
565 }
566 }
567 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000568
569 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000570 Py_DECREF(result_list);
571 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000572}
573
574static PyMethodDef poll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000575 {"register", (PyCFunction)poll_register,
576 METH_VARARGS, poll_register_doc},
577 {"modify", (PyCFunction)poll_modify,
578 METH_VARARGS, poll_modify_doc},
579 {"unregister", (PyCFunction)poll_unregister,
580 METH_O, poll_unregister_doc},
581 {"poll", (PyCFunction)poll_poll,
582 METH_VARARGS, poll_poll_doc},
583 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000584};
585
586static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000587newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000588{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000589 pollObject *self;
590 self = PyObject_New(pollObject, &poll_Type);
591 if (self == NULL)
592 return NULL;
593 /* ufd_uptodate is a Boolean, denoting whether the
594 array pointed to by ufds matches the contents of the dictionary. */
595 self->ufd_uptodate = 0;
596 self->ufds = NULL;
597 self->dict = PyDict_New();
598 if (self->dict == NULL) {
599 Py_DECREF(self);
600 return NULL;
601 }
602 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000603}
604
605static void
606poll_dealloc(pollObject *self)
607{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000608 if (self->ufds != NULL)
609 PyMem_DEL(self->ufds);
610 Py_XDECREF(self->dict);
611 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000612}
613
Tim Peters0c322792002-07-17 16:49:03 +0000614static PyTypeObject poll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000615 /* The ob_type field must be initialized in the module init function
616 * to be portable to Windows without using C++. */
617 PyVarObject_HEAD_INIT(NULL, 0)
618 "select.poll", /*tp_name*/
619 sizeof(pollObject), /*tp_basicsize*/
620 0, /*tp_itemsize*/
621 /* methods */
622 (destructor)poll_dealloc, /*tp_dealloc*/
623 0, /*tp_print*/
624 0, /*tp_getattr*/
625 0, /*tp_setattr*/
626 0, /*tp_reserved*/
627 0, /*tp_repr*/
628 0, /*tp_as_number*/
629 0, /*tp_as_sequence*/
630 0, /*tp_as_mapping*/
631 0, /*tp_hash*/
632 0, /*tp_call*/
633 0, /*tp_str*/
634 0, /*tp_getattro*/
635 0, /*tp_setattro*/
636 0, /*tp_as_buffer*/
637 Py_TPFLAGS_DEFAULT, /*tp_flags*/
638 0, /*tp_doc*/
639 0, /*tp_traverse*/
640 0, /*tp_clear*/
641 0, /*tp_richcompare*/
642 0, /*tp_weaklistoffset*/
643 0, /*tp_iter*/
644 0, /*tp_iternext*/
645 poll_methods, /*tp_methods*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000646};
647
Jesus Cead8b9ae62011-11-14 19:07:41 +0100648#ifdef HAVE_SYS_DEVPOLL_H
649typedef struct {
650 PyObject_HEAD
651 int fd_devpoll;
652 int max_n_fds;
653 int n_fds;
654 struct pollfd *fds;
655} devpollObject;
656
657static PyTypeObject devpoll_Type;
658
659static int devpoll_flush(devpollObject *self)
660{
661 int size, n;
662
663 if (!self->n_fds) return 0;
664
665 size = sizeof(struct pollfd)*self->n_fds;
666 self->n_fds = 0;
667
668 Py_BEGIN_ALLOW_THREADS
669 n = write(self->fd_devpoll, self->fds, size);
670 Py_END_ALLOW_THREADS
671
672 if (n == -1 ) {
673 PyErr_SetFromErrno(PyExc_IOError);
674 return -1;
675 }
676 if (n < size) {
677 /*
678 ** Data writed to /dev/poll is a binary data structure. It is not
679 ** clear what to do if a partial write occurred. For now, raise
680 ** an exception and see if we actually found this problem in
681 ** the wild.
682 ** See http://bugs.python.org/issue6397.
683 */
684 PyErr_Format(PyExc_IOError, "failed to write all pollfds. "
685 "Please, report at http://bugs.python.org/. "
686 "Data to report: Size tried: %d, actual size written: %d.",
687 size, n);
688 return -1;
689 }
690 return 0;
691}
692
693static PyObject *
694internal_devpoll_register(devpollObject *self, PyObject *args, int remove)
695{
696 PyObject *o;
697 int fd, events = POLLIN | POLLPRI | POLLOUT;
698
699 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
700 return NULL;
701 }
702
703 fd = PyObject_AsFileDescriptor(o);
704 if (fd == -1) return NULL;
705
706 if (remove) {
707 self->fds[self->n_fds].fd = fd;
708 self->fds[self->n_fds].events = POLLREMOVE;
709
710 if (++self->n_fds == self->max_n_fds) {
711 if (devpoll_flush(self))
712 return NULL;
713 }
714 }
715
716 self->fds[self->n_fds].fd = fd;
717 self->fds[self->n_fds].events = events;
718
719 if (++self->n_fds == self->max_n_fds) {
720 if (devpoll_flush(self))
721 return NULL;
722 }
723
724 Py_RETURN_NONE;
725}
726
727PyDoc_STRVAR(devpoll_register_doc,
728"register(fd [, eventmask] ) -> None\n\n\
729Register a file descriptor with the polling object.\n\
730fd -- either an integer, or an object with a fileno() method returning an\n\
731 int.\n\
732events -- an optional bitmask describing the type of events to check for");
733
734static PyObject *
735devpoll_register(devpollObject *self, PyObject *args)
736{
737 return internal_devpoll_register(self, args, 0);
738}
739
740PyDoc_STRVAR(devpoll_modify_doc,
741"modify(fd[, eventmask]) -> None\n\n\
742Modify a possible already registered file descriptor.\n\
743fd -- either an integer, or an object with a fileno() method returning an\n\
744 int.\n\
745events -- an optional bitmask describing the type of events to check for");
746
747static PyObject *
748devpoll_modify(devpollObject *self, PyObject *args)
749{
750 return internal_devpoll_register(self, args, 1);
751}
752
753
754PyDoc_STRVAR(devpoll_unregister_doc,
755"unregister(fd) -> None\n\n\
756Remove a file descriptor being tracked by the polling object.");
757
758static PyObject *
759devpoll_unregister(devpollObject *self, PyObject *o)
760{
761 int fd;
762
763 fd = PyObject_AsFileDescriptor( o );
764 if (fd == -1)
765 return NULL;
766
767 self->fds[self->n_fds].fd = fd;
768 self->fds[self->n_fds].events = POLLREMOVE;
769
770 if (++self->n_fds == self->max_n_fds) {
771 if (devpoll_flush(self))
772 return NULL;
773 }
774
775 Py_RETURN_NONE;
776}
777
778PyDoc_STRVAR(devpoll_poll_doc,
779"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
780Polls the set of registered file descriptors, returning a list containing \n\
781any descriptors that have events or errors to report.");
782
783static PyObject *
784devpoll_poll(devpollObject *self, PyObject *args)
785{
786 struct dvpoll dvp;
787 PyObject *result_list = NULL, *tout = NULL;
788 int poll_result, i;
789 long timeout;
790 PyObject *value, *num1, *num2;
791
792 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
793 return NULL;
794 }
795
796 /* Check values for timeout */
797 if (tout == NULL || tout == Py_None)
798 timeout = -1;
799 else if (!PyNumber_Check(tout)) {
800 PyErr_SetString(PyExc_TypeError,
801 "timeout must be an integer or None");
802 return NULL;
803 }
804 else {
805 tout = PyNumber_Long(tout);
806 if (!tout)
807 return NULL;
808 timeout = PyLong_AsLong(tout);
809 Py_DECREF(tout);
810 if (timeout == -1 && PyErr_Occurred())
811 return NULL;
812 }
813
814 if ((timeout < -1) || (timeout > INT_MAX)) {
815 PyErr_SetString(PyExc_OverflowError,
816 "timeout is out of range");
817 return NULL;
818 }
819
820 if (devpoll_flush(self))
821 return NULL;
822
823 dvp.dp_fds = self->fds;
824 dvp.dp_nfds = self->max_n_fds;
825 dvp.dp_timeout = timeout;
826
827 /* call devpoll() */
828 Py_BEGIN_ALLOW_THREADS
829 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
830 Py_END_ALLOW_THREADS
831
832 if (poll_result < 0) {
833 PyErr_SetFromErrno(PyExc_IOError);
834 return NULL;
835 }
836
837 /* build the result list */
838
839 result_list = PyList_New(poll_result);
840 if (!result_list)
841 return NULL;
842 else {
843 for (i = 0; i < poll_result; i++) {
844 num1 = PyLong_FromLong(self->fds[i].fd);
845 num2 = PyLong_FromLong(self->fds[i].revents);
846 if ((num1 == NULL) || (num2 == NULL)) {
847 Py_XDECREF(num1);
848 Py_XDECREF(num2);
849 goto error;
850 }
851 value = PyTuple_Pack(2, num1, num2);
852 Py_DECREF(num1);
853 Py_DECREF(num2);
854 if (value == NULL)
855 goto error;
856 if ((PyList_SetItem(result_list, i, value)) == -1) {
857 Py_DECREF(value);
858 goto error;
859 }
860 }
861 }
862
863 return result_list;
864
865 error:
866 Py_DECREF(result_list);
867 return NULL;
868}
869
870static PyMethodDef devpoll_methods[] = {
871 {"register", (PyCFunction)devpoll_register,
872 METH_VARARGS, devpoll_register_doc},
873 {"modify", (PyCFunction)devpoll_modify,
874 METH_VARARGS, devpoll_modify_doc},
875 {"unregister", (PyCFunction)devpoll_unregister,
876 METH_O, devpoll_unregister_doc},
877 {"poll", (PyCFunction)devpoll_poll,
878 METH_VARARGS, devpoll_poll_doc},
879 {NULL, NULL} /* sentinel */
880};
881
882static devpollObject *
883newDevPollObject(void)
884{
885 devpollObject *self;
886 int fd_devpoll, limit_result;
887 struct pollfd *fds;
888 struct rlimit limit;
889
890 Py_BEGIN_ALLOW_THREADS
891 /*
892 ** If we try to process more that getrlimit()
893 ** fds, the kernel will give an error, so
894 ** we set the limit here. It is a dynamic
895 ** value, because we can change rlimit() anytime.
896 */
897 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
898 if (limit_result != -1)
899 fd_devpoll = open("/dev/poll", O_RDWR);
900 Py_END_ALLOW_THREADS
901
902 if (limit_result == -1) {
903 PyErr_SetFromErrno(PyExc_OSError);
904 return NULL;
905 }
906 if (fd_devpoll == -1) {
907 PyErr_SetFromErrnoWithFilename(PyExc_IOError, "/dev/poll");
908 return NULL;
909 }
910
911 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
912 if (fds == NULL) {
913 close(fd_devpoll);
914 PyErr_NoMemory();
915 return NULL;
916 }
917
918 self = PyObject_New(devpollObject, &devpoll_Type);
919 if (self == NULL) {
920 close(fd_devpoll);
921 PyMem_DEL(fds);
922 return NULL;
923 }
924 self->fd_devpoll = fd_devpoll;
925 self->max_n_fds = limit.rlim_cur;
926 self->n_fds = 0;
927 self->fds = fds;
928
929 return self;
930}
931
932static void
933devpoll_dealloc(devpollObject *self)
934{
935 Py_BEGIN_ALLOW_THREADS
936 close(self->fd_devpoll);
937 Py_END_ALLOW_THREADS
938
939 PyMem_DEL(self->fds);
940
941 PyObject_Del(self);
942}
943
944static PyTypeObject devpoll_Type = {
945 /* The ob_type field must be initialized in the module init function
946 * to be portable to Windows without using C++. */
947 PyVarObject_HEAD_INIT(NULL, 0)
948 "select.devpoll", /*tp_name*/
949 sizeof(devpollObject), /*tp_basicsize*/
950 0, /*tp_itemsize*/
951 /* methods */
952 (destructor)devpoll_dealloc, /*tp_dealloc*/
953 0, /*tp_print*/
954 0, /*tp_getattr*/
955 0, /*tp_setattr*/
956 0, /*tp_reserved*/
957 0, /*tp_repr*/
958 0, /*tp_as_number*/
959 0, /*tp_as_sequence*/
960 0, /*tp_as_mapping*/
961 0, /*tp_hash*/
962 0, /*tp_call*/
963 0, /*tp_str*/
964 0, /*tp_getattro*/
965 0, /*tp_setattro*/
966 0, /*tp_as_buffer*/
967 Py_TPFLAGS_DEFAULT, /*tp_flags*/
968 0, /*tp_doc*/
969 0, /*tp_traverse*/
970 0, /*tp_clear*/
971 0, /*tp_richcompare*/
972 0, /*tp_weaklistoffset*/
973 0, /*tp_iter*/
974 0, /*tp_iternext*/
975 devpoll_methods, /*tp_methods*/
976};
977#endif /* HAVE_SYS_DEVPOLL_H */
978
979
980
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000981PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000982"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000983unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000984
985static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000986select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000987{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000988 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000989}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000990
Jesus Cead8b9ae62011-11-14 19:07:41 +0100991#ifdef HAVE_SYS_DEVPOLL_H
992PyDoc_STRVAR(devpoll_doc,
993"Returns a polling object, which supports registering and\n\
994unregistering file descriptors, and then polling them for I/O events.");
995
996static PyObject *
997select_devpoll(PyObject *self, PyObject *unused)
998{
999 return (PyObject *)newDevPollObject();
1000}
1001#endif
1002
1003
Thomas Wouters477c8d52006-05-27 19:21:47 +00001004#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001005/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001006 * On some systems poll() sets errno on invalid file descriptors. We test
1007 * for this at runtime because this bug may be fixed or introduced between
1008 * OS releases.
1009 */
1010static int select_have_broken_poll(void)
1011{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001012 int poll_test;
1013 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001014
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001015 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001016
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001017 /* Create a file descriptor to make invalid */
1018 if (pipe(filedes) < 0) {
1019 return 1;
1020 }
1021 poll_struct.fd = filedes[0];
1022 close(filedes[0]);
1023 close(filedes[1]);
1024 poll_test = poll(&poll_struct, 1, 0);
1025 if (poll_test < 0) {
1026 return 1;
1027 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1028 return 1;
1029 }
1030 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001031}
1032#endif /* __APPLE__ */
1033
1034#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001035
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001036#ifdef HAVE_EPOLL
1037/* **************************************************************************
1038 * epoll interface for Linux 2.6
1039 *
1040 * Written by Christian Heimes
1041 * Inspired by Twisted's _epoll.pyx and select.poll()
1042 */
1043
1044#ifdef HAVE_SYS_EPOLL_H
1045#include <sys/epoll.h>
1046#endif
1047
1048typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001049 PyObject_HEAD
1050 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001051} pyEpoll_Object;
1052
1053static PyTypeObject pyEpoll_Type;
1054#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
1055
1056static PyObject *
1057pyepoll_err_closed(void)
1058{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001059 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
1060 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001061}
1062
1063static int
1064pyepoll_internal_close(pyEpoll_Object *self)
1065{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001066 int save_errno = 0;
1067 if (self->epfd >= 0) {
1068 int epfd = self->epfd;
1069 self->epfd = -1;
1070 Py_BEGIN_ALLOW_THREADS
1071 if (close(epfd) < 0)
1072 save_errno = errno;
1073 Py_END_ALLOW_THREADS
1074 }
1075 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001076}
1077
1078static PyObject *
Benjamin Peterson95c16622011-12-27 15:36:32 -06001079newPyEpoll_Object(PyTypeObject *type, int sizehint, int flags, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001080{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001081 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001082
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001083 assert(type != NULL && type->tp_alloc != NULL);
1084 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
1085 if (self == NULL)
1086 return NULL;
1087
1088 if (fd == -1) {
1089 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001090#ifdef HAVE_EPOLL_CREATE1
Benjamin Peterson83251c12011-12-27 16:01:21 -06001091 if (flags)
1092 self->epfd = epoll_create1(flags);
1093 else
Benjamin Peterson95c16622011-12-27 15:36:32 -06001094#endif
Benjamin Peterson83251c12011-12-27 16:01:21 -06001095 self->epfd = epoll_create(sizehint);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001096 Py_END_ALLOW_THREADS
1097 }
1098 else {
1099 self->epfd = fd;
1100 }
1101 if (self->epfd < 0) {
1102 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001103 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001104 return NULL;
1105 }
1106 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001107}
1108
1109
1110static PyObject *
1111pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1112{
Benjamin Peterson83251c12011-12-27 16:01:21 -06001113 int flags = 0, sizehint = FD_SETSIZE - 1;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001114 static char *kwlist[] = {"sizehint", "flags", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001115
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001116 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:epoll", kwlist,
1117 &sizehint, &flags))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001118 return NULL;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001119 if (sizehint < 0) {
1120 PyErr_SetString(PyExc_ValueError, "negative sizehint");
1121 return NULL;
1122 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001123
Benjamin Peterson95c16622011-12-27 15:36:32 -06001124 return newPyEpoll_Object(type, sizehint, flags, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001125}
1126
1127
1128static void
1129pyepoll_dealloc(pyEpoll_Object *self)
1130{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001131 (void)pyepoll_internal_close(self);
1132 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001133}
1134
1135static PyObject*
1136pyepoll_close(pyEpoll_Object *self)
1137{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001138 errno = pyepoll_internal_close(self);
1139 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001140 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001141 return NULL;
1142 }
1143 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001144}
1145
1146PyDoc_STRVAR(pyepoll_close_doc,
1147"close() -> None\n\
1148\n\
1149Close the epoll control file descriptor. Further operations on the epoll\n\
1150object will raise an exception.");
1151
1152static PyObject*
1153pyepoll_get_closed(pyEpoll_Object *self)
1154{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001155 if (self->epfd < 0)
1156 Py_RETURN_TRUE;
1157 else
1158 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001159}
1160
1161static PyObject*
1162pyepoll_fileno(pyEpoll_Object *self)
1163{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001164 if (self->epfd < 0)
1165 return pyepoll_err_closed();
1166 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001167}
1168
1169PyDoc_STRVAR(pyepoll_fileno_doc,
1170"fileno() -> int\n\
1171\n\
1172Return the epoll control file descriptor.");
1173
1174static PyObject*
1175pyepoll_fromfd(PyObject *cls, PyObject *args)
1176{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001177 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001178
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001179 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1180 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001181
Benjamin Peterson95c16622011-12-27 15:36:32 -06001182 return newPyEpoll_Object((PyTypeObject*)cls, FD_SETSIZE - 1, 0, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001183}
1184
1185PyDoc_STRVAR(pyepoll_fromfd_doc,
1186"fromfd(fd) -> epoll\n\
1187\n\
1188Create an epoll object from a given control fd.");
1189
1190static PyObject *
1191pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
1192{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001193 struct epoll_event ev;
1194 int result;
1195 int fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001196
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001197 if (epfd < 0)
1198 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001199
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001200 fd = PyObject_AsFileDescriptor(pfd);
1201 if (fd == -1) {
1202 return NULL;
1203 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001204
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001205 switch(op) {
1206 case EPOLL_CTL_ADD:
1207 case EPOLL_CTL_MOD:
1208 ev.events = events;
1209 ev.data.fd = fd;
1210 Py_BEGIN_ALLOW_THREADS
1211 result = epoll_ctl(epfd, op, fd, &ev);
1212 Py_END_ALLOW_THREADS
1213 break;
1214 case EPOLL_CTL_DEL:
1215 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1216 * operation required a non-NULL pointer in event, even
1217 * though this argument is ignored. */
1218 Py_BEGIN_ALLOW_THREADS
1219 result = epoll_ctl(epfd, op, fd, &ev);
1220 if (errno == EBADF) {
1221 /* fd already closed */
1222 result = 0;
1223 errno = 0;
1224 }
1225 Py_END_ALLOW_THREADS
1226 break;
1227 default:
1228 result = -1;
1229 errno = EINVAL;
1230 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001232 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001233 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001234 return NULL;
1235 }
1236 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001237}
1238
1239static PyObject *
1240pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1241{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001242 PyObject *pfd;
1243 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
1244 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001245
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001246 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
1247 &pfd, &events)) {
1248 return NULL;
1249 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001250
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001251 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001252}
1253
1254PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl222569d2010-08-02 20:47:56 +00001255"register(fd[, eventmask]) -> None\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001256\n\
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001257Registers a new fd or raises an OSError if the fd is already registered.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001258fd is the target file descriptor of the operation.\n\
1259events is a bit set composed of the various EPOLL constants; the default\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001260is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
1261\n\
1262The epoll interface supports all file descriptors that support poll.");
1263
1264static PyObject *
1265pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1266{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001267 PyObject *pfd;
1268 unsigned int events;
1269 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001271 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
1272 &pfd, &events)) {
1273 return NULL;
1274 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001275
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001276 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001277}
1278
1279PyDoc_STRVAR(pyepoll_modify_doc,
1280"modify(fd, eventmask) -> None\n\
1281\n\
1282fd is the target file descriptor of the operation\n\
1283events is a bit set composed of the various EPOLL constants");
1284
1285static PyObject *
1286pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1287{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001288 PyObject *pfd;
1289 static char *kwlist[] = {"fd", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
1292 &pfd)) {
1293 return NULL;
1294 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001295
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001296 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001297}
1298
1299PyDoc_STRVAR(pyepoll_unregister_doc,
1300"unregister(fd) -> None\n\
1301\n\
1302fd is the target file descriptor of the operation.");
1303
1304static PyObject *
1305pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1306{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001307 double dtimeout = -1.;
1308 int timeout;
1309 int maxevents = -1;
1310 int nfds, i;
1311 PyObject *elist = NULL, *etuple = NULL;
1312 struct epoll_event *evs = NULL;
1313 static char *kwlist[] = {"timeout", "maxevents", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001314
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001315 if (self->epfd < 0)
1316 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
1319 &dtimeout, &maxevents)) {
1320 return NULL;
1321 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 if (dtimeout < 0) {
1324 timeout = -1;
1325 }
1326 else if (dtimeout * 1000.0 > INT_MAX) {
1327 PyErr_SetString(PyExc_OverflowError,
1328 "timeout is too large");
1329 return NULL;
1330 }
1331 else {
1332 timeout = (int)(dtimeout * 1000.0);
1333 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001335 if (maxevents == -1) {
1336 maxevents = FD_SETSIZE-1;
1337 }
1338 else if (maxevents < 1) {
1339 PyErr_Format(PyExc_ValueError,
1340 "maxevents must be greater than 0, got %d",
1341 maxevents);
1342 return NULL;
1343 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001345 evs = PyMem_New(struct epoll_event, maxevents);
1346 if (evs == NULL) {
1347 Py_DECREF(self);
1348 PyErr_NoMemory();
1349 return NULL;
1350 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001352 Py_BEGIN_ALLOW_THREADS
1353 nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
1354 Py_END_ALLOW_THREADS
1355 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001356 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001357 goto error;
1358 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001359
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001360 elist = PyList_New(nfds);
1361 if (elist == NULL) {
1362 goto error;
1363 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001364
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001365 for (i = 0; i < nfds; i++) {
1366 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
1367 if (etuple == NULL) {
1368 Py_CLEAR(elist);
1369 goto error;
1370 }
1371 PyList_SET_ITEM(elist, i, etuple);
1372 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001373
Christian Heimesf6cd9672008-03-26 13:45:42 +00001374 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 PyMem_Free(evs);
1376 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001377}
1378
1379PyDoc_STRVAR(pyepoll_poll_doc,
1380"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1381\n\
1382Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1383in seconds (as float). -1 makes poll wait indefinitely.\n\
1384Up to maxevents are returned to the caller.");
1385
1386static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001387 {"fromfd", (PyCFunction)pyepoll_fromfd,
1388 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1389 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1390 pyepoll_close_doc},
1391 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1392 pyepoll_fileno_doc},
1393 {"modify", (PyCFunction)pyepoll_modify,
1394 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1395 {"register", (PyCFunction)pyepoll_register,
1396 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1397 {"unregister", (PyCFunction)pyepoll_unregister,
1398 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1399 {"poll", (PyCFunction)pyepoll_poll,
1400 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
1401 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001402};
1403
1404static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001405 {"closed", (getter)pyepoll_get_closed, NULL,
1406 "True if the epoll handler is closed"},
1407 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001408};
1409
1410PyDoc_STRVAR(pyepoll_doc,
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001411"select.epoll(sizehint=-1, flags=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001412\n\
1413Returns an epolling object\n\
1414\n\
1415sizehint must be a positive integer or -1 for the default size. The\n\
1416sizehint is used to optimize internal data structures. It doesn't limit\n\
1417the maximum number of monitored events.");
1418
1419static PyTypeObject pyEpoll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001420 PyVarObject_HEAD_INIT(NULL, 0)
1421 "select.epoll", /* tp_name */
1422 sizeof(pyEpoll_Object), /* tp_basicsize */
1423 0, /* tp_itemsize */
1424 (destructor)pyepoll_dealloc, /* tp_dealloc */
1425 0, /* tp_print */
1426 0, /* tp_getattr */
1427 0, /* tp_setattr */
1428 0, /* tp_reserved */
1429 0, /* tp_repr */
1430 0, /* tp_as_number */
1431 0, /* tp_as_sequence */
1432 0, /* tp_as_mapping */
1433 0, /* tp_hash */
1434 0, /* tp_call */
1435 0, /* tp_str */
1436 PyObject_GenericGetAttr, /* tp_getattro */
1437 0, /* tp_setattro */
1438 0, /* tp_as_buffer */
1439 Py_TPFLAGS_DEFAULT, /* tp_flags */
1440 pyepoll_doc, /* tp_doc */
1441 0, /* tp_traverse */
1442 0, /* tp_clear */
1443 0, /* tp_richcompare */
1444 0, /* tp_weaklistoffset */
1445 0, /* tp_iter */
1446 0, /* tp_iternext */
1447 pyepoll_methods, /* tp_methods */
1448 0, /* tp_members */
1449 pyepoll_getsetlist, /* tp_getset */
1450 0, /* tp_base */
1451 0, /* tp_dict */
1452 0, /* tp_descr_get */
1453 0, /* tp_descr_set */
1454 0, /* tp_dictoffset */
1455 0, /* tp_init */
1456 0, /* tp_alloc */
1457 pyepoll_new, /* tp_new */
1458 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001459};
1460
1461#endif /* HAVE_EPOLL */
1462
1463#ifdef HAVE_KQUEUE
1464/* **************************************************************************
1465 * kqueue interface for BSD
1466 *
1467 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1468 * All rights reserved.
1469 *
1470 * Redistribution and use in source and binary forms, with or without
1471 * modification, are permitted provided that the following conditions
1472 * are met:
1473 * 1. Redistributions of source code must retain the above copyright
1474 * notice, this list of conditions and the following disclaimer.
1475 * 2. Redistributions in binary form must reproduce the above copyright
1476 * notice, this list of conditions and the following disclaimer in the
1477 * documentation and/or other materials provided with the distribution.
1478 *
1479 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1480 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1481 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1482 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1483 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1484 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1485 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1486 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1487 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1488 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1489 * SUCH DAMAGE.
1490 */
1491
1492#ifdef HAVE_SYS_EVENT_H
1493#include <sys/event.h>
1494#endif
1495
1496PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001497"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001498\n\
1499This object is the equivalent of the struct kevent for the C API.\n\
1500\n\
1501See the kqueue manpage for more detailed information about the meaning\n\
1502of the arguments.\n\
1503\n\
1504One minor note: while you might hope that udata could store a\n\
1505reference to a python object, it cannot, because it is impossible to\n\
1506keep a proper reference count of the object once it's passed into the\n\
1507kernel. Therefore, I have restricted it to only storing an integer. I\n\
1508recommend ignoring it and simply using the 'ident' field to key off\n\
1509of. You could also set up a dictionary on the python side to store a\n\
1510udata->object mapping.");
1511
1512typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001513 PyObject_HEAD
1514 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001515} kqueue_event_Object;
1516
1517static PyTypeObject kqueue_event_Type;
1518
1519#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1520
1521typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001522 PyObject_HEAD
1523 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001524} kqueue_queue_Object;
1525
1526static PyTypeObject kqueue_queue_Type;
1527
1528#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1529
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001530#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1531# error uintptr_t does not match void *!
1532#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1533# define T_UINTPTRT T_ULONGLONG
1534# define T_INTPTRT T_LONGLONG
1535# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1536# define UINTPTRT_FMT_UNIT "K"
1537# define INTPTRT_FMT_UNIT "L"
1538#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1539# define T_UINTPTRT T_ULONG
1540# define T_INTPTRT T_LONG
1541# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1542# define UINTPTRT_FMT_UNIT "k"
1543# define INTPTRT_FMT_UNIT "l"
1544#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1545# define T_UINTPTRT T_UINT
1546# define T_INTPTRT T_INT
1547# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1548# define UINTPTRT_FMT_UNIT "I"
1549# define INTPTRT_FMT_UNIT "i"
1550#else
1551# error uintptr_t does not match int, long, or long long!
1552#endif
1553
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001554/* Unfortunately, we can't store python objects in udata, because
1555 * kevents in the kernel can be removed without warning, which would
1556 * forever lose the refcount on the object stored with it.
1557 */
1558
1559#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1560static struct PyMemberDef kqueue_event_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001561 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1562 {"filter", T_SHORT, KQ_OFF(e.filter)},
1563 {"flags", T_USHORT, KQ_OFF(e.flags)},
1564 {"fflags", T_UINT, KQ_OFF(e.fflags)},
1565 {"data", T_INTPTRT, KQ_OFF(e.data)},
1566 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1567 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001568};
1569#undef KQ_OFF
1570
1571static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001572
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001573kqueue_event_repr(kqueue_event_Object *s)
1574{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001575 char buf[1024];
1576 PyOS_snprintf(
1577 buf, sizeof(buf),
1578 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1579 "data=0x%zd udata=%p>",
1580 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1581 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1582 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001583}
1584
1585static int
1586kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1587{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001588 PyObject *pfd;
1589 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1590 "data", "udata", NULL};
1591 static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001592
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001593 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001594
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001595 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1596 &pfd, &(self->e.filter), &(self->e.flags),
1597 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1598 return -1;
1599 }
1600
1601 if (PyLong_Check(pfd)) {
1602 self->e.ident = PyLong_AsUintptr_t(pfd);
1603 }
1604 else {
1605 self->e.ident = PyObject_AsFileDescriptor(pfd);
1606 }
1607 if (PyErr_Occurred()) {
1608 return -1;
1609 }
1610 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001611}
1612
1613static PyObject *
1614kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001615 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001616{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001617 Py_intptr_t result = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001618
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001619 if (!kqueue_event_Check(o)) {
1620 if (op == Py_EQ || op == Py_NE) {
1621 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1622 Py_INCREF(res);
1623 return res;
1624 }
1625 PyErr_Format(PyExc_TypeError,
1626 "can't compare %.200s to %.200s",
1627 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1628 return NULL;
1629 }
1630 if (((result = s->e.ident - o->e.ident) == 0) &&
1631 ((result = s->e.filter - o->e.filter) == 0) &&
1632 ((result = s->e.flags - o->e.flags) == 0) &&
1633 ((result = s->e.fflags - o->e.fflags) == 0) &&
1634 ((result = s->e.data - o->e.data) == 0) &&
1635 ((result = s->e.udata - o->e.udata) == 0)
1636 ) {
1637 result = 0;
1638 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001639
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001640 switch (op) {
1641 case Py_EQ:
1642 result = (result == 0);
1643 break;
1644 case Py_NE:
1645 result = (result != 0);
1646 break;
1647 case Py_LE:
1648 result = (result <= 0);
1649 break;
1650 case Py_GE:
1651 result = (result >= 0);
1652 break;
1653 case Py_LT:
1654 result = (result < 0);
1655 break;
1656 case Py_GT:
1657 result = (result > 0);
1658 break;
1659 }
1660 return PyBool_FromLong((long)result);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001661}
1662
1663static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001664 PyVarObject_HEAD_INIT(NULL, 0)
1665 "select.kevent", /* tp_name */
1666 sizeof(kqueue_event_Object), /* tp_basicsize */
1667 0, /* tp_itemsize */
1668 0, /* tp_dealloc */
1669 0, /* tp_print */
1670 0, /* tp_getattr */
1671 0, /* tp_setattr */
1672 0, /* tp_reserved */
1673 (reprfunc)kqueue_event_repr, /* tp_repr */
1674 0, /* tp_as_number */
1675 0, /* tp_as_sequence */
1676 0, /* tp_as_mapping */
1677 0, /* tp_hash */
1678 0, /* tp_call */
1679 0, /* tp_str */
1680 0, /* tp_getattro */
1681 0, /* tp_setattro */
1682 0, /* tp_as_buffer */
1683 Py_TPFLAGS_DEFAULT, /* tp_flags */
1684 kqueue_event_doc, /* tp_doc */
1685 0, /* tp_traverse */
1686 0, /* tp_clear */
1687 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1688 0, /* tp_weaklistoffset */
1689 0, /* tp_iter */
1690 0, /* tp_iternext */
1691 0, /* tp_methods */
1692 kqueue_event_members, /* tp_members */
1693 0, /* tp_getset */
1694 0, /* tp_base */
1695 0, /* tp_dict */
1696 0, /* tp_descr_get */
1697 0, /* tp_descr_set */
1698 0, /* tp_dictoffset */
1699 (initproc)kqueue_event_init, /* tp_init */
1700 0, /* tp_alloc */
1701 0, /* tp_new */
1702 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001703};
1704
1705static PyObject *
1706kqueue_queue_err_closed(void)
1707{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001708 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1709 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001710}
1711
1712static int
1713kqueue_queue_internal_close(kqueue_queue_Object *self)
1714{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001715 int save_errno = 0;
1716 if (self->kqfd >= 0) {
1717 int kqfd = self->kqfd;
1718 self->kqfd = -1;
1719 Py_BEGIN_ALLOW_THREADS
1720 if (close(kqfd) < 0)
1721 save_errno = errno;
1722 Py_END_ALLOW_THREADS
1723 }
1724 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001725}
1726
1727static PyObject *
1728newKqueue_Object(PyTypeObject *type, SOCKET fd)
1729{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001730 kqueue_queue_Object *self;
1731 assert(type != NULL && type->tp_alloc != NULL);
1732 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1733 if (self == NULL) {
1734 return NULL;
1735 }
1736
1737 if (fd == -1) {
1738 Py_BEGIN_ALLOW_THREADS
1739 self->kqfd = kqueue();
1740 Py_END_ALLOW_THREADS
1741 }
1742 else {
1743 self->kqfd = fd;
1744 }
1745 if (self->kqfd < 0) {
1746 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001747 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001748 return NULL;
1749 }
1750 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001751}
1752
1753static PyObject *
1754kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1755{
1756
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001757 if ((args != NULL && PyObject_Size(args)) ||
1758 (kwds != NULL && PyObject_Size(kwds))) {
1759 PyErr_SetString(PyExc_ValueError,
1760 "select.kqueue doesn't accept arguments");
1761 return NULL;
1762 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001763
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001764 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001765}
1766
1767static void
1768kqueue_queue_dealloc(kqueue_queue_Object *self)
1769{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001770 kqueue_queue_internal_close(self);
1771 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001772}
1773
1774static PyObject*
1775kqueue_queue_close(kqueue_queue_Object *self)
1776{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001777 errno = kqueue_queue_internal_close(self);
1778 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001779 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001780 return NULL;
1781 }
1782 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001783}
1784
1785PyDoc_STRVAR(kqueue_queue_close_doc,
1786"close() -> None\n\
1787\n\
1788Close the kqueue control file descriptor. Further operations on the kqueue\n\
1789object will raise an exception.");
1790
1791static PyObject*
1792kqueue_queue_get_closed(kqueue_queue_Object *self)
1793{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001794 if (self->kqfd < 0)
1795 Py_RETURN_TRUE;
1796 else
1797 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001798}
1799
1800static PyObject*
1801kqueue_queue_fileno(kqueue_queue_Object *self)
1802{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001803 if (self->kqfd < 0)
1804 return kqueue_queue_err_closed();
1805 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001806}
1807
1808PyDoc_STRVAR(kqueue_queue_fileno_doc,
1809"fileno() -> int\n\
1810\n\
1811Return the kqueue control file descriptor.");
1812
1813static PyObject*
1814kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1815{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001816 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001817
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001818 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1819 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001820
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001821 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001822}
1823
1824PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1825"fromfd(fd) -> kqueue\n\
1826\n\
1827Create a kqueue object from a given control fd.");
1828
1829static PyObject *
1830kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1831{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001832 int nevents = 0;
1833 int gotevents = 0;
1834 int nchanges = 0;
1835 int i = 0;
1836 PyObject *otimeout = NULL;
1837 PyObject *ch = NULL;
1838 PyObject *it = NULL, *ei = NULL;
1839 PyObject *result = NULL;
1840 struct kevent *evl = NULL;
1841 struct kevent *chl = NULL;
Victor Stinnerd327f9d2012-03-13 15:29:08 +01001842 struct timespec timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001843 struct timespec *ptimeoutspec;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001844
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001845 if (self->kqfd < 0)
1846 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001847
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001848 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1849 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001850
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001851 if (nevents < 0) {
1852 PyErr_Format(PyExc_ValueError,
1853 "Length of eventlist must be 0 or positive, got %d",
1854 nevents);
1855 return NULL;
1856 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001857
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001858 if (otimeout == Py_None || otimeout == NULL) {
1859 ptimeoutspec = NULL;
1860 }
1861 else if (PyNumber_Check(otimeout)) {
Victor Stinner5d272cc2012-03-13 13:35:55 +01001862 if (_PyTime_ObjectToTimespec(otimeout,
1863 &timeout.tv_sec, &timeout.tv_nsec) == -1)
1864 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001865
Victor Stinner5d272cc2012-03-13 13:35:55 +01001866 if (timeout.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001867 PyErr_SetString(PyExc_ValueError,
1868 "timeout must be positive or None");
1869 return NULL;
1870 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001871 ptimeoutspec = &timeoutspec;
1872 }
1873 else {
1874 PyErr_Format(PyExc_TypeError,
1875 "timeout argument must be an number "
1876 "or None, got %.200s",
1877 Py_TYPE(otimeout)->tp_name);
1878 return NULL;
1879 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001880
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001881 if (ch != NULL && ch != Py_None) {
1882 it = PyObject_GetIter(ch);
1883 if (it == NULL) {
1884 PyErr_SetString(PyExc_TypeError,
1885 "changelist is not iterable");
1886 return NULL;
1887 }
1888 nchanges = PyObject_Size(ch);
1889 if (nchanges < 0) {
1890 goto error;
1891 }
Georg Brandlc0e22b72010-03-14 10:51:01 +00001892
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001893 chl = PyMem_New(struct kevent, nchanges);
1894 if (chl == NULL) {
1895 PyErr_NoMemory();
1896 goto error;
1897 }
1898 i = 0;
1899 while ((ei = PyIter_Next(it)) != NULL) {
1900 if (!kqueue_event_Check(ei)) {
1901 Py_DECREF(ei);
1902 PyErr_SetString(PyExc_TypeError,
1903 "changelist must be an iterable of "
1904 "select.kevent objects");
1905 goto error;
1906 } else {
1907 chl[i++] = ((kqueue_event_Object *)ei)->e;
1908 }
1909 Py_DECREF(ei);
1910 }
1911 }
1912 Py_CLEAR(it);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001913
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001914 /* event list */
1915 if (nevents) {
1916 evl = PyMem_New(struct kevent, nevents);
1917 if (evl == NULL) {
1918 PyErr_NoMemory();
1919 goto error;
1920 }
1921 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001922
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001923 Py_BEGIN_ALLOW_THREADS
1924 gotevents = kevent(self->kqfd, chl, nchanges,
1925 evl, nevents, ptimeoutspec);
1926 Py_END_ALLOW_THREADS
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001927
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001928 if (gotevents == -1) {
1929 PyErr_SetFromErrno(PyExc_OSError);
1930 goto error;
1931 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001932
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001933 result = PyList_New(gotevents);
1934 if (result == NULL) {
1935 goto error;
1936 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001938 for (i = 0; i < gotevents; i++) {
1939 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001940
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001941 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1942 if (ch == NULL) {
1943 goto error;
1944 }
1945 ch->e = evl[i];
1946 PyList_SET_ITEM(result, i, (PyObject *)ch);
1947 }
1948 PyMem_Free(chl);
1949 PyMem_Free(evl);
1950 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001951
1952 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001953 PyMem_Free(chl);
1954 PyMem_Free(evl);
1955 Py_XDECREF(result);
1956 Py_XDECREF(it);
1957 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001958}
1959
1960PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00001961"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001962\n\
1963Calls the kernel kevent function.\n\
1964- changelist must be a list of kevent objects describing the changes\n\
1965 to be made to the kernel's watch list or None.\n\
1966- max_events lets you specify the maximum number of events that the\n\
1967 kernel will return.\n\
1968- timeout is the maximum time to wait in seconds, or else None,\n\
1969 to wait forever. timeout accepts floats for smaller timeouts, too.");
1970
1971
1972static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001973 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
1974 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
1975 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
1976 kqueue_queue_close_doc},
1977 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
1978 kqueue_queue_fileno_doc},
1979 {"control", (PyCFunction)kqueue_queue_control,
1980 METH_VARARGS , kqueue_queue_control_doc},
1981 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001982};
1983
1984static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001985 {"closed", (getter)kqueue_queue_get_closed, NULL,
1986 "True if the kqueue handler is closed"},
1987 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001988};
1989
1990PyDoc_STRVAR(kqueue_queue_doc,
1991"Kqueue syscall wrapper.\n\
1992\n\
1993For example, to start watching a socket for input:\n\
1994>>> kq = kqueue()\n\
1995>>> sock = socket()\n\
1996>>> sock.connect((host, port))\n\
1997>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
1998\n\
1999To wait one second for it to become writeable:\n\
2000>>> kq.control(None, 1, 1000)\n\
2001\n\
2002To stop listening:\n\
2003>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
2004
2005static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002006 PyVarObject_HEAD_INIT(NULL, 0)
2007 "select.kqueue", /* tp_name */
2008 sizeof(kqueue_queue_Object), /* tp_basicsize */
2009 0, /* tp_itemsize */
2010 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
2011 0, /* tp_print */
2012 0, /* tp_getattr */
2013 0, /* tp_setattr */
2014 0, /* tp_reserved */
2015 0, /* tp_repr */
2016 0, /* tp_as_number */
2017 0, /* tp_as_sequence */
2018 0, /* tp_as_mapping */
2019 0, /* tp_hash */
2020 0, /* tp_call */
2021 0, /* tp_str */
2022 0, /* tp_getattro */
2023 0, /* tp_setattro */
2024 0, /* tp_as_buffer */
2025 Py_TPFLAGS_DEFAULT, /* tp_flags */
2026 kqueue_queue_doc, /* tp_doc */
2027 0, /* tp_traverse */
2028 0, /* tp_clear */
2029 0, /* tp_richcompare */
2030 0, /* tp_weaklistoffset */
2031 0, /* tp_iter */
2032 0, /* tp_iternext */
2033 kqueue_queue_methods, /* tp_methods */
2034 0, /* tp_members */
2035 kqueue_queue_getsetlist, /* tp_getset */
2036 0, /* tp_base */
2037 0, /* tp_dict */
2038 0, /* tp_descr_get */
2039 0, /* tp_descr_set */
2040 0, /* tp_dictoffset */
2041 0, /* tp_init */
2042 0, /* tp_alloc */
2043 kqueue_queue_new, /* tp_new */
2044 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002045};
2046
2047#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002048
2049
2050
2051
2052
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002053/* ************************************************************************ */
2054
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002055PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002056"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
2057\n\
2058Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00002059The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002060rlist -- wait until ready for reading\n\
2061wlist -- wait until ready for writing\n\
2062xlist -- wait for an ``exceptional condition''\n\
2063If only one kind of condition is required, pass [] for the other lists.\n\
2064A file descriptor is either a socket or file object, or a small integer\n\
2065gotten from a fileno() method call on one of those.\n\
2066\n\
2067The optional 4th argument specifies a timeout in seconds; it may be\n\
2068a floating point number to specify fractions of seconds. If it is absent\n\
2069or None, the call will never time out.\n\
2070\n\
2071The return value is a tuple of three lists corresponding to the first three\n\
2072arguments; each contains the subset of the corresponding file descriptors\n\
2073that are ready.\n\
2074\n\
2075*** IMPORTANT NOTICE ***\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002076On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00002077descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002078
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002079static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002080 {"select", select_select, METH_VARARGS, select_doc},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002081#ifdef HAVE_POLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002082 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00002083#endif /* HAVE_POLL */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002084#ifdef HAVE_SYS_DEVPOLL_H
2085 {"devpoll", select_devpoll, METH_NOARGS, devpoll_doc},
2086#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002087 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002088};
2089
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002090PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002091"This module supports asynchronous I/O on multiple file descriptors.\n\
2092\n\
2093*** IMPORTANT NOTICE ***\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002094On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002095
Martin v. Löwis1a214512008-06-11 05:26:20 +00002096
2097static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002098 PyModuleDef_HEAD_INIT,
2099 "select",
2100 module_doc,
2101 -1,
2102 select_methods,
2103 NULL,
2104 NULL,
2105 NULL,
2106 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002107};
2108
Jesus Cead8b9ae62011-11-14 19:07:41 +01002109
2110
2111
Mark Hammond62b1ab12002-07-23 06:31:15 +00002112PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002113PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002114{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002115 PyObject *m;
2116 m = PyModule_Create(&selectmodule);
2117 if (m == NULL)
2118 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002119
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002120 Py_INCREF(PyExc_OSError);
2121 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002122
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002123#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002124#ifdef HAVE_BROKEN_PIPE_BUF
2125#undef PIPE_BUF
2126#define PIPE_BUF 512
2127#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002128 PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002129#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002130
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002131#if defined(HAVE_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002132#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002133 if (select_have_broken_poll()) {
2134 if (PyObject_DelAttrString(m, "poll") == -1) {
2135 PyErr_Clear();
2136 }
2137 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002138#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002139 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002140#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002141 if (PyType_Ready(&poll_Type) < 0)
2142 return NULL;
2143 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
2144 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
2145 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
2146 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
2147 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
2148 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002149
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002150#ifdef POLLRDNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002151 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002152#endif
2153#ifdef POLLRDBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002154 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002155#endif
2156#ifdef POLLWRNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002157 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002158#endif
2159#ifdef POLLWRBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002160 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002161#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002162#ifdef POLLMSG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002163 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002164#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002165 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002166#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002167
Jesus Cead8b9ae62011-11-14 19:07:41 +01002168#ifdef HAVE_SYS_DEVPOLL_H
2169 if (PyType_Ready(&devpoll_Type) < 0)
2170 return NULL;
2171#endif
2172
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002173#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002174 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
2175 if (PyType_Ready(&pyEpoll_Type) < 0)
2176 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002177
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002178 Py_INCREF(&pyEpoll_Type);
2179 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002180
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002181 PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
2182 PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
2183 PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
2184 PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
2185 PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
2186 PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002187#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002188 /* Kernel 2.6.2+ */
2189 PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002190#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002191 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
2192 PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
2193 PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
2194 PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
2195 PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
2196 PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002197
Benjamin Peterson95c16622011-12-27 15:36:32 -06002198#ifdef EPOLL_CLOEXEC
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002199 PyModule_AddIntConstant(m, "EPOLL_CLOEXEC", EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002200#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002201#endif /* HAVE_EPOLL */
2202
2203#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002204 kqueue_event_Type.tp_new = PyType_GenericNew;
2205 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
2206 if(PyType_Ready(&kqueue_event_Type) < 0)
2207 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002208
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002209 Py_INCREF(&kqueue_event_Type);
2210 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002211
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002212 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
2213 if(PyType_Ready(&kqueue_queue_Type) < 0)
2214 return NULL;
2215 Py_INCREF(&kqueue_queue_Type);
2216 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
2217
2218 /* event filters */
2219 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2220 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
2221 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
2222 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
2223 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002224#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002225 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002226#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002227 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
2228 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002229
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002230 /* event flags */
2231 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2232 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2233 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2234 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2235 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2236 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002237
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002238 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
2239 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002240
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002241 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2242 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002243
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002244 /* READ WRITE filter flag */
2245 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002247 /* VNODE filter flags */
2248 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2249 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2250 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2251 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2252 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2253 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2254 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002256 /* PROC filter flags */
2257 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2258 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2259 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2260 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2261 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002263 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2264 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2265 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
2266
2267 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002268#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002269 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2270 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2271 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002272#endif
2273
2274#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002275 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002276}