blob: 44ff3dd18b49985127bd8a44c27fbf54ec4fa97b [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
Guido van Rossum6f489d91996-06-28 20:15:15 +000050#ifdef MS_WINDOWS
Christian Heimesc36625b2008-01-04 13:33:00 +000051# define WIN32_LEAN_AND_MEAN
Thomas Wouters0e3f5912006-08-11 14:57:12 +000052# include <winsock.h>
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000053#else
Thomas Wouters0e3f5912006-08-11 14:57:12 +000054# define SOCKET int
Guido van Rossumbcc20741998-08-04 22:53:56 +000055#endif
Guido van Rossumed233a51992-06-23 09:07:03 +000056
Barry Warsawc1cb3601996-12-12 22:16:21 +000057/* list of Python objects and their file descriptor */
58typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000059 PyObject *obj; /* owned reference */
60 SOCKET fd;
61 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000062} pylist;
63
Barry Warsawc1cb3601996-12-12 22:16:21 +000064static void
Tim Peters4b046c22001-08-16 21:59:46 +000065reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +000066{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000067 int i;
68 for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +020069 Py_CLEAR(fd2obj[i].obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000070 }
71 fd2obj[0].sentinel = -1;
Barry Warsawc1cb3601996-12-12 22:16:21 +000072}
73
74
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000075/* returns -1 and sets the Python exception if an error occurred, otherwise
76 returns a number >= 0
77*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000078static int
Brett Cannon62dba4c2003-09-10 19:37:42 +000079seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +000080{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000081 int max = -1;
82 int index = 0;
Antoine Pitroue4ad37e2012-11-01 20:13:54 +010083 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084 PyObject* fast_seq = NULL;
85 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000086
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000087 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
88 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000089
Benjamin Petersone0edb8b2010-06-27 23:49:45 +000090 fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000091 if (!fast_seq)
92 return -1;
93
Antoine Pitroue4ad37e2012-11-01 20:13:54 +010094 for (i = 0; i < PySequence_Fast_GET_SIZE(fast_seq); i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000095 SOCKET v;
96
97 /* any intervening fileno() calls could decr this refcnt */
98 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Jesus Cea62a5c322012-07-19 21:31:26 +020099 goto finally;
Brett Cannon62dba4c2003-09-10 19:37:42 +0000100
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000101 Py_INCREF(o);
102 v = PyObject_AsFileDescriptor( o );
103 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000104
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000105#if defined(_MSC_VER)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000106 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000107#else /* !_MSC_VER */
Charles-François Nataliaa26b272011-08-28 17:51:43 +0200108 if (!_PyIsSelectable_fd(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000109 PyErr_SetString(PyExc_ValueError,
110 "filedescriptor out of range in select()");
111 goto finally;
112 }
113 if (v > max)
114 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000115#endif /* _MSC_VER */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000116 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000117
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000118 /* add object and its file descriptor to the list */
119 if (index >= FD_SETSIZE) {
120 PyErr_SetString(PyExc_ValueError,
121 "too many file descriptors in select()");
122 goto finally;
123 }
124 fd2obj[index].obj = o;
125 fd2obj[index].fd = v;
126 fd2obj[index].sentinel = 0;
127 fd2obj[++index].sentinel = -1;
128 }
129 Py_DECREF(fast_seq);
130 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000131
132 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000133 Py_XDECREF(o);
134 Py_DECREF(fast_seq);
135 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000136}
137
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000138/* returns NULL and sets the Python exception if an error occurred */
139static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000140set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000141{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000142 int i, j, count=0;
143 PyObject *list, *o;
144 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000145
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000146 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
147 if (FD_ISSET(fd2obj[j].fd, set))
148 count++;
149 }
150 list = PyList_New(count);
151 if (!list)
152 return NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000154 i = 0;
155 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
156 fd = fd2obj[j].fd;
157 if (FD_ISSET(fd, set)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000158 o = fd2obj[j].obj;
159 fd2obj[j].obj = NULL;
160 /* transfer ownership */
161 if (PyList_SetItem(list, i, o) < 0)
162 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000164 i++;
165 }
166 }
167 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000168 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000169 Py_DECREF(list);
170 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000171}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000172
Barry Warsawb44740f2001-08-16 16:52:59 +0000173#undef SELECT_USES_HEAP
174#if FD_SETSIZE > 1024
175#define SELECT_USES_HEAP
176#endif /* FD_SETSIZE > 1024 */
177
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000178static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000179select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000180{
Barry Warsawb44740f2001-08-16 16:52:59 +0000181#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000182 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000183#else /* !SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000184 /* XXX: All this should probably be implemented as follows:
185 * - find the highest descriptor we're interested in
186 * - add one
187 * - that's the size
188 * See: Stevens, APitUE, $12.5.1
189 */
190 pylist rfd2obj[FD_SETSIZE + 1];
191 pylist wfd2obj[FD_SETSIZE + 1];
192 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000193#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000194 PyObject *ifdlist, *ofdlist, *efdlist;
195 PyObject *ret = NULL;
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200196 PyObject *timeout_obj = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000197 fd_set ifdset, ofdset, efdset;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000198 struct timeval tv, *tvp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000199 int imax, omax, emax, max;
200 int n;
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200201 _PyTime_t timeout, deadline = 0;
Guido van Rossumed233a51992-06-23 09:07:03 +0000202
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000203 /* convert arguments */
204 if (!PyArg_UnpackTuple(args, "select", 3, 4,
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200205 &ifdlist, &ofdlist, &efdlist, &timeout_obj))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000206 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000207
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200208 if (timeout_obj == Py_None)
209 tvp = (struct timeval *)NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000210 else {
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200211 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
212 _PyTime_ROUND_CEILING) < 0) {
213 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
214 PyErr_SetString(PyExc_TypeError,
215 "timeout must be a float or None");
216 }
Victor Stinnerb2a37732012-03-14 00:20:51 +0100217 return NULL;
218 }
Victor Stinnerc3378382015-03-28 05:07:51 +0100219
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200220 if (_PyTime_AsTimeval(timeout, &tv, _PyTime_ROUND_CEILING) == -1)
Victor Stinnerc3378382015-03-28 05:07:51 +0100221 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +0100222 if (tv.tv_sec < 0) {
223 PyErr_SetString(PyExc_ValueError, "timeout must be non-negative");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000224 return NULL;
225 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000226 tvp = &tv;
227 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000228
Barry Warsawb44740f2001-08-16 16:52:59 +0000229#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000230 /* Allocate memory for the lists */
231 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
232 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
233 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
234 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
235 if (rfd2obj) PyMem_DEL(rfd2obj);
236 if (wfd2obj) PyMem_DEL(wfd2obj);
237 if (efd2obj) PyMem_DEL(efd2obj);
238 return PyErr_NoMemory();
239 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000240#endif /* SELECT_USES_HEAP */
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200241
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000242 /* Convert sequences to fd_sets, and get maximum fd number
243 * propagates the Python exception set in seq2set()
244 */
245 rfd2obj[0].sentinel = -1;
246 wfd2obj[0].sentinel = -1;
247 efd2obj[0].sentinel = -1;
248 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
249 goto finally;
250 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
251 goto finally;
252 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
253 goto finally;
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200254
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000255 max = imax;
256 if (omax > max) max = omax;
257 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000258
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200259 if (tvp)
260 deadline = _PyTime_GetMonotonicClock() + timeout;
261
262 do {
263 Py_BEGIN_ALLOW_THREADS
264 errno = 0;
265 n = select(max, &ifdset, &ofdset, &efdset, tvp);
266 Py_END_ALLOW_THREADS
267
268 if (errno != EINTR)
269 break;
270
271 /* select() was interrupted by a signal */
272 if (PyErr_CheckSignals())
273 goto finally;
274
275 if (tvp) {
276 timeout = deadline - _PyTime_GetMonotonicClock();
277 if (timeout < 0) {
278 n = 0;
279 break;
280 }
281 _PyTime_AsTimeval_noraise(timeout, &tv, _PyTime_ROUND_CEILING);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200282 /* retry select() with the recomputed timeout */
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200283 }
284 } while (1);
Guido van Rossumed233a51992-06-23 09:07:03 +0000285
Thomas Heller106f4c72002-09-24 16:51:00 +0000286#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000287 if (n == SOCKET_ERROR) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200288 PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000289 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000290#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000291 if (n < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200292 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000293 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000294#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000295 else {
296 /* any of these three calls can raise an exception. it's more
297 convenient to test for this after all three calls... but
298 is that acceptable?
299 */
300 ifdlist = set2list(&ifdset, rfd2obj);
301 ofdlist = set2list(&ofdset, wfd2obj);
302 efdlist = set2list(&efdset, efd2obj);
303 if (PyErr_Occurred())
304 ret = NULL;
305 else
306 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000307
Victor Stinnerbbf8ce52013-07-09 00:49:03 +0200308 Py_XDECREF(ifdlist);
309 Py_XDECREF(ofdlist);
310 Py_XDECREF(efdlist);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000311 }
312
Barry Warsawc1cb3601996-12-12 22:16:21 +0000313 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000314 reap_obj(rfd2obj);
315 reap_obj(wfd2obj);
316 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000317#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 PyMem_DEL(rfd2obj);
319 PyMem_DEL(wfd2obj);
320 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000321#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000323}
324
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000325#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000327 * poll() support
328 */
329
330typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000331 PyObject_HEAD
332 PyObject *dict;
333 int ufd_uptodate;
334 int ufd_len;
335 struct pollfd *ufds;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300336 int poll_running;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000337} pollObject;
338
Jeremy Hylton938ace62002-07-17 16:30:39 +0000339static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000340
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000341/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000342 contained within a pollObject. Return 1 on success, 0 on an error.
343*/
344
345static int
346update_ufd_array(pollObject *self)
347{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000348 Py_ssize_t i, pos;
349 PyObject *key, *value;
350 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000352 self->ufd_len = PyDict_Size(self->dict);
353 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
354 if (self->ufds == NULL) {
355 self->ufds = old_ufds;
356 PyErr_NoMemory();
357 return 0;
358 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000359
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000360 i = pos = 0;
361 while (PyDict_Next(self->dict, &pos, &key, &value)) {
Serhiy Storchaka78980432013-01-15 01:12:17 +0200362 assert(i < self->ufd_len);
363 /* Never overflow */
364 self->ufds[i].fd = (int)PyLong_AsLong(key);
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200365 self->ufds[i].events = (short)(unsigned short)PyLong_AsLong(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000366 i++;
367 }
Serhiy Storchaka78980432013-01-15 01:12:17 +0200368 assert(i == self->ufd_len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000369 self->ufd_uptodate = 1;
370 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000371}
372
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200373static int
374ushort_converter(PyObject *obj, void *ptr)
375{
376 unsigned long uval;
377
378 uval = PyLong_AsUnsignedLong(obj);
379 if (uval == (unsigned long)-1 && PyErr_Occurred())
380 return 0;
381 if (uval > USHRT_MAX) {
382 PyErr_SetString(PyExc_OverflowError,
383 "Python int too large for C unsigned short");
384 return 0;
385 }
386
387 *(unsigned short *)ptr = Py_SAFE_DOWNCAST(uval, unsigned long, unsigned short);
388 return 1;
389}
390
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000391PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000392"register(fd [, eventmask] ) -> None\n\n\
393Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000394fd -- either an integer, or an object with a fileno() method returning an\n\
395 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000396events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000397
398static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000399poll_register(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000400{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000401 PyObject *o, *key, *value;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200402 int fd;
403 unsigned short events = POLLIN | POLLPRI | POLLOUT;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000404 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000405
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200406 if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000408
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000409 fd = PyObject_AsFileDescriptor(o);
410 if (fd == -1) return NULL;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000411
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000412 /* Add entry to the internal dictionary: the key is the
413 file descriptor, and the value is the event mask. */
414 key = PyLong_FromLong(fd);
415 if (key == NULL)
416 return NULL;
417 value = PyLong_FromLong(events);
418 if (value == NULL) {
419 Py_DECREF(key);
420 return NULL;
421 }
422 err = PyDict_SetItem(self->dict, key, value);
423 Py_DECREF(key);
424 Py_DECREF(value);
425 if (err < 0)
426 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000427
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000428 self->ufd_uptodate = 0;
429
430 Py_INCREF(Py_None);
431 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000432}
433
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000434PyDoc_STRVAR(poll_modify_doc,
435"modify(fd, eventmask) -> None\n\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000436Modify an already registered file descriptor.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000437fd -- either an integer, or an object with a fileno() method returning an\n\
438 int.\n\
439events -- an optional bitmask describing the type of events to check for");
440
441static PyObject *
442poll_modify(pollObject *self, PyObject *args)
443{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000444 PyObject *o, *key, *value;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200445 int fd;
446 unsigned short events;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000447 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000448
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200449 if (!PyArg_ParseTuple(args, "OO&:modify", &o, ushort_converter, &events))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000450 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000451
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000452 fd = PyObject_AsFileDescriptor(o);
453 if (fd == -1) return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000454
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000455 /* Modify registered fd */
456 key = PyLong_FromLong(fd);
457 if (key == NULL)
458 return NULL;
459 if (PyDict_GetItem(self->dict, key) == NULL) {
460 errno = ENOENT;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200461 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cea62a5c322012-07-19 21:31:26 +0200462 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000463 return NULL;
464 }
465 value = PyLong_FromLong(events);
466 if (value == NULL) {
467 Py_DECREF(key);
468 return NULL;
469 }
470 err = PyDict_SetItem(self->dict, key, value);
471 Py_DECREF(key);
472 Py_DECREF(value);
473 if (err < 0)
474 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000475
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000476 self->ufd_uptodate = 0;
477
478 Py_INCREF(Py_None);
479 return Py_None;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000480}
481
482
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000483PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000484"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000485Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000486
487static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000488poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000489{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000490 PyObject *key;
491 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000492
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000493 fd = PyObject_AsFileDescriptor( o );
494 if (fd == -1)
495 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000496
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000497 /* Check whether the fd is already in the array */
498 key = PyLong_FromLong(fd);
499 if (key == NULL)
500 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000501
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000502 if (PyDict_DelItem(self->dict, key) == -1) {
503 Py_DECREF(key);
504 /* This will simply raise the KeyError set by PyDict_DelItem
505 if the file descriptor isn't registered. */
506 return NULL;
507 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 Py_DECREF(key);
510 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000512 Py_INCREF(Py_None);
513 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000514}
515
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000516PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000517"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
518Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000519any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000520
521static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000522poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000523{
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200524 PyObject *result_list = NULL, *timeout_obj = NULL;
525 int poll_result, i, j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000526 PyObject *value = NULL, *num = NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200527 _PyTime_t timeout, ms, deadline;
528 int async_err = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000529
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200530 if (!PyArg_ParseTuple(args, "|O:poll", &timeout_obj)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000531 return NULL;
532 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000533
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000534 /* Check values for timeout */
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200535 if (timeout_obj == NULL || timeout_obj == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000536 timeout = -1;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200537 ms = -1;
Victor Stinner41eba222015-03-30 21:59:21 +0200538 deadline = 0; /* initialize to prevent gcc warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000539 }
540 else {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200541 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
542 _PyTime_ROUND_CEILING) < 0) {
543 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
544 PyErr_SetString(PyExc_TypeError,
545 "timeout must be an integer or None");
546 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000547 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200548 }
549
550 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
551 if (ms < INT_MIN || ms > INT_MAX) {
552 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000553 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200554 }
555
556 deadline = _PyTime_GetMonotonicClock() + timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000557 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000558
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300559 /* Avoid concurrent poll() invocation, issue 8865 */
560 if (self->poll_running) {
561 PyErr_SetString(PyExc_RuntimeError,
562 "concurrent poll() invocation");
563 return NULL;
564 }
565
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000566 /* Ensure the ufd array is up to date */
567 if (!self->ufd_uptodate)
568 if (update_ufd_array(self) == 0)
569 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000570
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300571 self->poll_running = 1;
572
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000573 /* call poll() */
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200574 async_err = 0;
575 do {
576 Py_BEGIN_ALLOW_THREADS
577 errno = 0;
578 poll_result = poll(self->ufds, self->ufd_len, (int)ms);
579 Py_END_ALLOW_THREADS
580
581 if (errno != EINTR)
582 break;
583
584 /* poll() was interrupted by a signal */
585 if (PyErr_CheckSignals()) {
586 async_err = 1;
587 break;
588 }
589
590 if (timeout >= 0) {
591 timeout = deadline - _PyTime_GetMonotonicClock();
592 if (timeout < 0) {
593 poll_result = 0;
594 break;
595 }
596 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
597 /* retry poll() with the recomputed timeout */
598 }
599 } while (1);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000600
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300601 self->poll_running = 0;
602
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000603 if (poll_result < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200604 if (!async_err)
605 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000606 return NULL;
607 }
608
609 /* build the result list */
610
611 result_list = PyList_New(poll_result);
612 if (!result_list)
613 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000614
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200615 for (i = 0, j = 0; j < poll_result; j++) {
616 /* skip to the next fired descriptor */
617 while (!self->ufds[i].revents) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000618 i++;
619 }
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200620 /* if we hit a NULL return, set value to NULL
621 and break out of loop; code at end will
622 clean up result_list */
623 value = PyTuple_New(2);
624 if (value == NULL)
625 goto error;
626 num = PyLong_FromLong(self->ufds[i].fd);
627 if (num == NULL) {
628 Py_DECREF(value);
629 goto error;
630 }
631 PyTuple_SET_ITEM(value, 0, num);
632
633 /* The &0xffff is a workaround for AIX. 'revents'
634 is a 16-bit short, and IBM assigned POLLNVAL
635 to be 0x8000, so the conversion to int results
636 in a negative number. See SF bug #923315. */
637 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
638 if (num == NULL) {
639 Py_DECREF(value);
640 goto error;
641 }
642 PyTuple_SET_ITEM(value, 1, num);
643 if ((PyList_SetItem(result_list, j, value)) == -1) {
644 Py_DECREF(value);
645 goto error;
646 }
647 i++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 }
649 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000650
651 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000652 Py_DECREF(result_list);
653 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000654}
655
656static PyMethodDef poll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000657 {"register", (PyCFunction)poll_register,
658 METH_VARARGS, poll_register_doc},
659 {"modify", (PyCFunction)poll_modify,
660 METH_VARARGS, poll_modify_doc},
661 {"unregister", (PyCFunction)poll_unregister,
662 METH_O, poll_unregister_doc},
663 {"poll", (PyCFunction)poll_poll,
664 METH_VARARGS, poll_poll_doc},
665 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000666};
667
668static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000669newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000670{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000671 pollObject *self;
672 self = PyObject_New(pollObject, &poll_Type);
673 if (self == NULL)
674 return NULL;
675 /* ufd_uptodate is a Boolean, denoting whether the
676 array pointed to by ufds matches the contents of the dictionary. */
677 self->ufd_uptodate = 0;
678 self->ufds = NULL;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300679 self->poll_running = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000680 self->dict = PyDict_New();
681 if (self->dict == NULL) {
682 Py_DECREF(self);
683 return NULL;
684 }
685 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000686}
687
688static void
689poll_dealloc(pollObject *self)
690{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000691 if (self->ufds != NULL)
692 PyMem_DEL(self->ufds);
693 Py_XDECREF(self->dict);
694 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000695}
696
Tim Peters0c322792002-07-17 16:49:03 +0000697static PyTypeObject poll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000698 /* The ob_type field must be initialized in the module init function
699 * to be portable to Windows without using C++. */
700 PyVarObject_HEAD_INIT(NULL, 0)
701 "select.poll", /*tp_name*/
702 sizeof(pollObject), /*tp_basicsize*/
703 0, /*tp_itemsize*/
704 /* methods */
705 (destructor)poll_dealloc, /*tp_dealloc*/
706 0, /*tp_print*/
707 0, /*tp_getattr*/
708 0, /*tp_setattr*/
709 0, /*tp_reserved*/
710 0, /*tp_repr*/
711 0, /*tp_as_number*/
712 0, /*tp_as_sequence*/
713 0, /*tp_as_mapping*/
714 0, /*tp_hash*/
715 0, /*tp_call*/
716 0, /*tp_str*/
717 0, /*tp_getattro*/
718 0, /*tp_setattro*/
719 0, /*tp_as_buffer*/
720 Py_TPFLAGS_DEFAULT, /*tp_flags*/
721 0, /*tp_doc*/
722 0, /*tp_traverse*/
723 0, /*tp_clear*/
724 0, /*tp_richcompare*/
725 0, /*tp_weaklistoffset*/
726 0, /*tp_iter*/
727 0, /*tp_iternext*/
728 poll_methods, /*tp_methods*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000729};
730
Jesus Cead8b9ae62011-11-14 19:07:41 +0100731#ifdef HAVE_SYS_DEVPOLL_H
732typedef struct {
733 PyObject_HEAD
734 int fd_devpoll;
735 int max_n_fds;
736 int n_fds;
737 struct pollfd *fds;
738} devpollObject;
739
740static PyTypeObject devpoll_Type;
741
Victor Stinner13423c32013-08-22 00:19:50 +0200742static PyObject *
743devpoll_err_closed(void)
744{
745 PyErr_SetString(PyExc_ValueError, "I/O operation on closed devpoll object");
746 return NULL;
747}
748
Jesus Cead8b9ae62011-11-14 19:07:41 +0100749static int devpoll_flush(devpollObject *self)
750{
751 int size, n;
752
753 if (!self->n_fds) return 0;
754
755 size = sizeof(struct pollfd)*self->n_fds;
756 self->n_fds = 0;
757
Victor Stinner54799672015-03-19 23:33:09 +0100758 n = _Py_write(self->fd_devpoll, self->fds, size);
759 if (n == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100760 return -1;
Victor Stinner54799672015-03-19 23:33:09 +0100761
Jesus Cead8b9ae62011-11-14 19:07:41 +0100762 if (n < size) {
763 /*
764 ** Data writed to /dev/poll is a binary data structure. It is not
765 ** clear what to do if a partial write occurred. For now, raise
766 ** an exception and see if we actually found this problem in
767 ** the wild.
768 ** See http://bugs.python.org/issue6397.
769 */
770 PyErr_Format(PyExc_IOError, "failed to write all pollfds. "
771 "Please, report at http://bugs.python.org/. "
772 "Data to report: Size tried: %d, actual size written: %d.",
773 size, n);
774 return -1;
775 }
776 return 0;
777}
778
779static PyObject *
780internal_devpoll_register(devpollObject *self, PyObject *args, int remove)
781{
782 PyObject *o;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200783 int fd;
784 unsigned short events = POLLIN | POLLPRI | POLLOUT;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100785
Victor Stinner13423c32013-08-22 00:19:50 +0200786 if (self->fd_devpoll < 0)
787 return devpoll_err_closed();
788
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200789 if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events))
Jesus Cead8b9ae62011-11-14 19:07:41 +0100790 return NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100791
792 fd = PyObject_AsFileDescriptor(o);
793 if (fd == -1) return NULL;
794
795 if (remove) {
796 self->fds[self->n_fds].fd = fd;
797 self->fds[self->n_fds].events = POLLREMOVE;
798
799 if (++self->n_fds == self->max_n_fds) {
800 if (devpoll_flush(self))
801 return NULL;
802 }
803 }
804
805 self->fds[self->n_fds].fd = fd;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200806 self->fds[self->n_fds].events = (signed short)events;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100807
808 if (++self->n_fds == self->max_n_fds) {
809 if (devpoll_flush(self))
810 return NULL;
811 }
812
813 Py_RETURN_NONE;
814}
815
816PyDoc_STRVAR(devpoll_register_doc,
817"register(fd [, eventmask] ) -> None\n\n\
818Register a file descriptor with the polling object.\n\
819fd -- either an integer, or an object with a fileno() method returning an\n\
820 int.\n\
821events -- an optional bitmask describing the type of events to check for");
822
823static PyObject *
824devpoll_register(devpollObject *self, PyObject *args)
825{
826 return internal_devpoll_register(self, args, 0);
827}
828
829PyDoc_STRVAR(devpoll_modify_doc,
830"modify(fd[, eventmask]) -> None\n\n\
831Modify a possible already registered file descriptor.\n\
832fd -- either an integer, or an object with a fileno() method returning an\n\
833 int.\n\
834events -- an optional bitmask describing the type of events to check for");
835
836static PyObject *
837devpoll_modify(devpollObject *self, PyObject *args)
838{
839 return internal_devpoll_register(self, args, 1);
840}
841
842
843PyDoc_STRVAR(devpoll_unregister_doc,
844"unregister(fd) -> None\n\n\
845Remove a file descriptor being tracked by the polling object.");
846
847static PyObject *
848devpoll_unregister(devpollObject *self, PyObject *o)
849{
850 int fd;
851
Victor Stinner13423c32013-08-22 00:19:50 +0200852 if (self->fd_devpoll < 0)
853 return devpoll_err_closed();
854
Jesus Cead8b9ae62011-11-14 19:07:41 +0100855 fd = PyObject_AsFileDescriptor( o );
856 if (fd == -1)
857 return NULL;
858
859 self->fds[self->n_fds].fd = fd;
860 self->fds[self->n_fds].events = POLLREMOVE;
861
862 if (++self->n_fds == self->max_n_fds) {
863 if (devpoll_flush(self))
864 return NULL;
865 }
866
867 Py_RETURN_NONE;
868}
869
870PyDoc_STRVAR(devpoll_poll_doc,
871"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
872Polls the set of registered file descriptors, returning a list containing \n\
873any descriptors that have events or errors to report.");
874
875static PyObject *
876devpoll_poll(devpollObject *self, PyObject *args)
877{
878 struct dvpoll dvp;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200879 PyObject *result_list = NULL, *timeout_obj = NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100880 int poll_result, i;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100881 PyObject *value, *num1, *num2;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200882 _PyTime_t timeout, ms, deadline = 0;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100883
Victor Stinner13423c32013-08-22 00:19:50 +0200884 if (self->fd_devpoll < 0)
885 return devpoll_err_closed();
886
Victor Stinner45ca48b2015-03-31 12:10:33 +0200887 if (!PyArg_ParseTuple(args, "|O:poll", &timeout_obj)) {
Jesus Cead8b9ae62011-11-14 19:07:41 +0100888 return NULL;
889 }
890
891 /* Check values for timeout */
Victor Stinner45ca48b2015-03-31 12:10:33 +0200892 if (timeout_obj == NULL || timeout_obj == Py_None) {
Jesus Cead8b9ae62011-11-14 19:07:41 +0100893 timeout = -1;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200894 ms = -1;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100895 }
896 else {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200897 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
898 _PyTime_ROUND_CEILING) < 0) {
899 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
900 PyErr_SetString(PyExc_TypeError,
901 "timeout must be an integer or None");
902 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100903 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200904 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100905
Victor Stinner45ca48b2015-03-31 12:10:33 +0200906 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
907 if (ms < -1 || ms > INT_MAX) {
908 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
909 return NULL;
910 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100911 }
912
913 if (devpoll_flush(self))
914 return NULL;
915
916 dvp.dp_fds = self->fds;
917 dvp.dp_nfds = self->max_n_fds;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200918 dvp.dp_timeout = (int)ms;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100919
Victor Stinner45ca48b2015-03-31 12:10:33 +0200920 if (timeout >= 0)
921 deadline = _PyTime_GetMonotonicClock() + timeout;
922
923 do {
924 /* call devpoll() */
925 Py_BEGIN_ALLOW_THREADS
926 errno = 0;
927 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
928 Py_END_ALLOW_THREADS
929
930 if (errno != EINTR)
931 break;
932
933 /* devpoll() was interrupted by a signal */
934 if (PyErr_CheckSignals())
935 return NULL;
936
937 if (timeout >= 0) {
938 timeout = deadline - _PyTime_GetMonotonicClock();
939 if (timeout < 0) {
940 poll_result = 0;
941 break;
942 }
943 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
944 dvp.dp_timeout = (int)ms;
945 /* retry devpoll() with the recomputed timeout */
946 }
947 } while (1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100948
949 if (poll_result < 0) {
950 PyErr_SetFromErrno(PyExc_IOError);
951 return NULL;
952 }
953
954 /* build the result list */
Jesus Cead8b9ae62011-11-14 19:07:41 +0100955 result_list = PyList_New(poll_result);
956 if (!result_list)
957 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200958
959 for (i = 0; i < poll_result; i++) {
960 num1 = PyLong_FromLong(self->fds[i].fd);
961 num2 = PyLong_FromLong(self->fds[i].revents);
962 if ((num1 == NULL) || (num2 == NULL)) {
963 Py_XDECREF(num1);
964 Py_XDECREF(num2);
965 goto error;
966 }
967 value = PyTuple_Pack(2, num1, num2);
968 Py_DECREF(num1);
969 Py_DECREF(num2);
970 if (value == NULL)
971 goto error;
972 if ((PyList_SetItem(result_list, i, value)) == -1) {
973 Py_DECREF(value);
974 goto error;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100975 }
976 }
977
978 return result_list;
979
980 error:
981 Py_DECREF(result_list);
982 return NULL;
983}
984
Richard Oudkerk168d59b2013-08-22 13:31:15 +0100985static int
986devpoll_internal_close(devpollObject *self)
987{
988 int save_errno = 0;
989 if (self->fd_devpoll >= 0) {
990 int fd = self->fd_devpoll;
991 self->fd_devpoll = -1;
992 Py_BEGIN_ALLOW_THREADS
993 if (close(fd) < 0)
994 save_errno = errno;
995 Py_END_ALLOW_THREADS
996 }
997 return save_errno;
998}
999
Victor Stinner13423c32013-08-22 00:19:50 +02001000static PyObject*
1001devpoll_close(devpollObject *self)
1002{
1003 errno = devpoll_internal_close(self);
1004 if (errno < 0) {
1005 PyErr_SetFromErrno(PyExc_OSError);
1006 return NULL;
1007 }
1008 Py_RETURN_NONE;
1009}
1010
1011PyDoc_STRVAR(devpoll_close_doc,
1012"close() -> None\n\
1013\n\
1014Close the devpoll file descriptor. Further operations on the devpoll\n\
1015object will raise an exception.");
1016
1017static PyObject*
1018devpoll_get_closed(devpollObject *self)
1019{
1020 if (self->fd_devpoll < 0)
1021 Py_RETURN_TRUE;
1022 else
1023 Py_RETURN_FALSE;
1024}
1025
1026static PyObject*
1027devpoll_fileno(devpollObject *self)
1028{
1029 if (self->fd_devpoll < 0)
1030 return devpoll_err_closed();
1031 return PyLong_FromLong(self->fd_devpoll);
1032}
1033
1034PyDoc_STRVAR(devpoll_fileno_doc,
1035"fileno() -> int\n\
1036\n\
1037Return the file descriptor.");
1038
Jesus Cead8b9ae62011-11-14 19:07:41 +01001039static PyMethodDef devpoll_methods[] = {
1040 {"register", (PyCFunction)devpoll_register,
1041 METH_VARARGS, devpoll_register_doc},
1042 {"modify", (PyCFunction)devpoll_modify,
1043 METH_VARARGS, devpoll_modify_doc},
1044 {"unregister", (PyCFunction)devpoll_unregister,
1045 METH_O, devpoll_unregister_doc},
1046 {"poll", (PyCFunction)devpoll_poll,
1047 METH_VARARGS, devpoll_poll_doc},
Victor Stinner13423c32013-08-22 00:19:50 +02001048 {"close", (PyCFunction)devpoll_close, METH_NOARGS,
1049 devpoll_close_doc},
1050 {"fileno", (PyCFunction)devpoll_fileno, METH_NOARGS,
1051 devpoll_fileno_doc},
Jesus Cead8b9ae62011-11-14 19:07:41 +01001052 {NULL, NULL} /* sentinel */
1053};
1054
Victor Stinner13423c32013-08-22 00:19:50 +02001055static PyGetSetDef devpoll_getsetlist[] = {
1056 {"closed", (getter)devpoll_get_closed, NULL,
1057 "True if the devpoll object is closed"},
1058 {0},
1059};
1060
Jesus Cead8b9ae62011-11-14 19:07:41 +01001061static devpollObject *
1062newDevPollObject(void)
1063{
1064 devpollObject *self;
1065 int fd_devpoll, limit_result;
1066 struct pollfd *fds;
1067 struct rlimit limit;
1068
Jesus Cead8b9ae62011-11-14 19:07:41 +01001069 /*
1070 ** If we try to process more that getrlimit()
1071 ** fds, the kernel will give an error, so
1072 ** we set the limit here. It is a dynamic
1073 ** value, because we can change rlimit() anytime.
1074 */
1075 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001076 if (limit_result == -1) {
1077 PyErr_SetFromErrno(PyExc_OSError);
1078 return NULL;
1079 }
Victor Stinnera555cfc2015-03-18 00:22:14 +01001080
1081 fd_devpoll = _Py_open("/dev/poll", O_RDWR);
1082 if (fd_devpoll == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +01001083 return NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +01001084
1085 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
1086 if (fds == NULL) {
1087 close(fd_devpoll);
1088 PyErr_NoMemory();
1089 return NULL;
1090 }
1091
1092 self = PyObject_New(devpollObject, &devpoll_Type);
1093 if (self == NULL) {
1094 close(fd_devpoll);
1095 PyMem_DEL(fds);
1096 return NULL;
1097 }
1098 self->fd_devpoll = fd_devpoll;
1099 self->max_n_fds = limit.rlim_cur;
1100 self->n_fds = 0;
1101 self->fds = fds;
1102
1103 return self;
1104}
1105
1106static void
1107devpoll_dealloc(devpollObject *self)
1108{
Richard Oudkerka93bf7b2013-08-22 14:03:44 +01001109 (void)devpoll_internal_close(self);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001110 PyMem_DEL(self->fds);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001111 PyObject_Del(self);
1112}
1113
1114static PyTypeObject devpoll_Type = {
1115 /* The ob_type field must be initialized in the module init function
1116 * to be portable to Windows without using C++. */
1117 PyVarObject_HEAD_INIT(NULL, 0)
1118 "select.devpoll", /*tp_name*/
1119 sizeof(devpollObject), /*tp_basicsize*/
1120 0, /*tp_itemsize*/
1121 /* methods */
1122 (destructor)devpoll_dealloc, /*tp_dealloc*/
1123 0, /*tp_print*/
1124 0, /*tp_getattr*/
1125 0, /*tp_setattr*/
1126 0, /*tp_reserved*/
1127 0, /*tp_repr*/
1128 0, /*tp_as_number*/
1129 0, /*tp_as_sequence*/
1130 0, /*tp_as_mapping*/
1131 0, /*tp_hash*/
1132 0, /*tp_call*/
1133 0, /*tp_str*/
1134 0, /*tp_getattro*/
1135 0, /*tp_setattro*/
1136 0, /*tp_as_buffer*/
1137 Py_TPFLAGS_DEFAULT, /*tp_flags*/
1138 0, /*tp_doc*/
1139 0, /*tp_traverse*/
1140 0, /*tp_clear*/
1141 0, /*tp_richcompare*/
1142 0, /*tp_weaklistoffset*/
1143 0, /*tp_iter*/
1144 0, /*tp_iternext*/
1145 devpoll_methods, /*tp_methods*/
Victor Stinner13423c32013-08-22 00:19:50 +02001146 0, /* tp_members */
1147 devpoll_getsetlist, /* tp_getset */
Jesus Cead8b9ae62011-11-14 19:07:41 +01001148};
1149#endif /* HAVE_SYS_DEVPOLL_H */
1150
1151
1152
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001153PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001154"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001155unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001156
1157static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001158select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001159{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001160 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001161}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001162
Jesus Cead8b9ae62011-11-14 19:07:41 +01001163#ifdef HAVE_SYS_DEVPOLL_H
1164PyDoc_STRVAR(devpoll_doc,
1165"Returns a polling object, which supports registering and\n\
1166unregistering file descriptors, and then polling them for I/O events.");
1167
1168static PyObject *
1169select_devpoll(PyObject *self, PyObject *unused)
1170{
1171 return (PyObject *)newDevPollObject();
1172}
1173#endif
1174
1175
Thomas Wouters477c8d52006-05-27 19:21:47 +00001176#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001177/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001178 * On some systems poll() sets errno on invalid file descriptors. We test
1179 * for this at runtime because this bug may be fixed or introduced between
1180 * OS releases.
1181 */
1182static int select_have_broken_poll(void)
1183{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001184 int poll_test;
1185 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001186
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001187 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001188
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001189 /* Create a file descriptor to make invalid */
1190 if (pipe(filedes) < 0) {
1191 return 1;
1192 }
1193 poll_struct.fd = filedes[0];
1194 close(filedes[0]);
1195 close(filedes[1]);
1196 poll_test = poll(&poll_struct, 1, 0);
1197 if (poll_test < 0) {
1198 return 1;
1199 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1200 return 1;
1201 }
1202 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001203}
1204#endif /* __APPLE__ */
1205
1206#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001207
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001208#ifdef HAVE_EPOLL
1209/* **************************************************************************
1210 * epoll interface for Linux 2.6
1211 *
1212 * Written by Christian Heimes
1213 * Inspired by Twisted's _epoll.pyx and select.poll()
1214 */
1215
1216#ifdef HAVE_SYS_EPOLL_H
1217#include <sys/epoll.h>
1218#endif
1219
1220typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001221 PyObject_HEAD
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001222 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001223} pyEpoll_Object;
1224
1225static PyTypeObject pyEpoll_Type;
1226#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
1227
1228static PyObject *
1229pyepoll_err_closed(void)
1230{
Victor Stinner13423c32013-08-22 00:19:50 +02001231 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001232 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001233}
1234
1235static int
1236pyepoll_internal_close(pyEpoll_Object *self)
1237{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001238 int save_errno = 0;
1239 if (self->epfd >= 0) {
1240 int epfd = self->epfd;
1241 self->epfd = -1;
1242 Py_BEGIN_ALLOW_THREADS
1243 if (close(epfd) < 0)
1244 save_errno = errno;
1245 Py_END_ALLOW_THREADS
1246 }
1247 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001248}
1249
1250static PyObject *
Benjamin Peterson95c16622011-12-27 15:36:32 -06001251newPyEpoll_Object(PyTypeObject *type, int sizehint, int flags, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001252{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001253 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001254
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001255 assert(type != NULL && type->tp_alloc != NULL);
1256 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
1257 if (self == NULL)
1258 return NULL;
1259
1260 if (fd == -1) {
1261 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001262#ifdef HAVE_EPOLL_CREATE1
Victor Stinnerdaf45552013-08-28 00:53:59 +02001263 flags |= EPOLL_CLOEXEC;
Benjamin Peterson83251c12011-12-27 16:01:21 -06001264 if (flags)
1265 self->epfd = epoll_create1(flags);
1266 else
Benjamin Peterson95c16622011-12-27 15:36:32 -06001267#endif
Benjamin Peterson83251c12011-12-27 16:01:21 -06001268 self->epfd = epoll_create(sizehint);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001269 Py_END_ALLOW_THREADS
1270 }
1271 else {
1272 self->epfd = fd;
1273 }
1274 if (self->epfd < 0) {
1275 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001276 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001277 return NULL;
1278 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001279
1280#ifndef HAVE_EPOLL_CREATE1
Victor Stinnerd72fe892013-08-28 12:22:39 +02001281 if (fd == -1 && _Py_set_inheritable(self->epfd, 0, NULL) < 0) {
Victor Stinnerdaf45552013-08-28 00:53:59 +02001282 Py_DECREF(self);
1283 return NULL;
1284 }
1285#endif
1286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001287 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001288}
1289
1290
1291static PyObject *
1292pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1293{
Benjamin Peterson83251c12011-12-27 16:01:21 -06001294 int flags = 0, sizehint = FD_SETSIZE - 1;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001295 static char *kwlist[] = {"sizehint", "flags", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001296
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001297 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:epoll", kwlist,
1298 &sizehint, &flags))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001299 return NULL;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001300 if (sizehint < 0) {
1301 PyErr_SetString(PyExc_ValueError, "negative sizehint");
1302 return NULL;
1303 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001304
Benjamin Peterson95c16622011-12-27 15:36:32 -06001305 return newPyEpoll_Object(type, sizehint, flags, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001306}
1307
1308
1309static void
1310pyepoll_dealloc(pyEpoll_Object *self)
1311{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 (void)pyepoll_internal_close(self);
1313 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001314}
1315
1316static PyObject*
1317pyepoll_close(pyEpoll_Object *self)
1318{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001319 errno = pyepoll_internal_close(self);
1320 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001321 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001322 return NULL;
1323 }
1324 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001325}
1326
1327PyDoc_STRVAR(pyepoll_close_doc,
1328"close() -> None\n\
1329\n\
1330Close the epoll control file descriptor. Further operations on the epoll\n\
1331object will raise an exception.");
1332
1333static PyObject*
1334pyepoll_get_closed(pyEpoll_Object *self)
1335{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001336 if (self->epfd < 0)
1337 Py_RETURN_TRUE;
1338 else
1339 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001340}
1341
1342static PyObject*
1343pyepoll_fileno(pyEpoll_Object *self)
1344{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001345 if (self->epfd < 0)
1346 return pyepoll_err_closed();
1347 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001348}
1349
1350PyDoc_STRVAR(pyepoll_fileno_doc,
1351"fileno() -> int\n\
1352\n\
1353Return the epoll control file descriptor.");
1354
1355static PyObject*
1356pyepoll_fromfd(PyObject *cls, PyObject *args)
1357{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001358 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001359
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001360 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1361 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001362
Benjamin Peterson95c16622011-12-27 15:36:32 -06001363 return newPyEpoll_Object((PyTypeObject*)cls, FD_SETSIZE - 1, 0, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001364}
1365
1366PyDoc_STRVAR(pyepoll_fromfd_doc,
1367"fromfd(fd) -> epoll\n\
1368\n\
1369Create an epoll object from a given control fd.");
1370
1371static PyObject *
1372pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
1373{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001374 struct epoll_event ev;
1375 int result;
1376 int fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001377
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001378 if (epfd < 0)
1379 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001381 fd = PyObject_AsFileDescriptor(pfd);
1382 if (fd == -1) {
1383 return NULL;
1384 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001385
Guido van Rossumee07b942013-12-06 17:46:22 -08001386 switch (op) {
1387 case EPOLL_CTL_ADD:
1388 case EPOLL_CTL_MOD:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001389 ev.events = events;
1390 ev.data.fd = fd;
1391 Py_BEGIN_ALLOW_THREADS
1392 result = epoll_ctl(epfd, op, fd, &ev);
1393 Py_END_ALLOW_THREADS
1394 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001395 case EPOLL_CTL_DEL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001396 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1397 * operation required a non-NULL pointer in event, even
1398 * though this argument is ignored. */
1399 Py_BEGIN_ALLOW_THREADS
1400 result = epoll_ctl(epfd, op, fd, &ev);
1401 if (errno == EBADF) {
1402 /* fd already closed */
1403 result = 0;
1404 errno = 0;
1405 }
1406 Py_END_ALLOW_THREADS
1407 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001408 default:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001409 result = -1;
1410 errno = EINVAL;
1411 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001412
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001413 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001414 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001415 return NULL;
1416 }
1417 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001418}
1419
1420static PyObject *
1421pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1422{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001423 PyObject *pfd;
1424 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
1425 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001426
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001427 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
1428 &pfd, &events)) {
1429 return NULL;
1430 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001431
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001432 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001433}
1434
1435PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl222569d2010-08-02 20:47:56 +00001436"register(fd[, eventmask]) -> None\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001437\n\
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001438Registers a new fd or raises an OSError if the fd is already registered.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001439fd is the target file descriptor of the operation.\n\
1440events is a bit set composed of the various EPOLL constants; the default\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001441is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
1442\n\
1443The epoll interface supports all file descriptors that support poll.");
1444
1445static PyObject *
1446pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1447{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001448 PyObject *pfd;
1449 unsigned int events;
1450 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001451
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001452 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
1453 &pfd, &events)) {
1454 return NULL;
1455 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001456
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001457 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001458}
1459
1460PyDoc_STRVAR(pyepoll_modify_doc,
1461"modify(fd, eventmask) -> None\n\
1462\n\
1463fd is the target file descriptor of the operation\n\
1464events is a bit set composed of the various EPOLL constants");
1465
1466static PyObject *
1467pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1468{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001469 PyObject *pfd;
1470 static char *kwlist[] = {"fd", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001471
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001472 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
1473 &pfd)) {
1474 return NULL;
1475 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001476
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001477 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001478}
1479
1480PyDoc_STRVAR(pyepoll_unregister_doc,
1481"unregister(fd) -> None\n\
1482\n\
1483fd is the target file descriptor of the operation.");
1484
1485static PyObject *
1486pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1487{
Victor Stinner41eba222015-03-30 21:59:21 +02001488 static char *kwlist[] = {"timeout", "maxevents", NULL};
1489 PyObject *timeout_obj = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001490 int maxevents = -1;
1491 int nfds, i;
1492 PyObject *elist = NULL, *etuple = NULL;
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001493 struct epoll_event *evs = NULL;
Victor Stinner41eba222015-03-30 21:59:21 +02001494 _PyTime_t timeout, ms, deadline;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001495
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001496 if (self->epfd < 0)
1497 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001498
Victor Stinner41eba222015-03-30 21:59:21 +02001499 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:poll", kwlist,
1500 &timeout_obj, &maxevents)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001501 return NULL;
1502 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001503
Victor Stinner41eba222015-03-30 21:59:21 +02001504 if (timeout_obj == NULL || timeout_obj == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001505 timeout = -1;
Victor Stinner41eba222015-03-30 21:59:21 +02001506 ms = -1;
1507 deadline = 0; /* initialize to prevent gcc warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001508 }
1509 else {
Victor Stinner41eba222015-03-30 21:59:21 +02001510 /* epoll_wait() has a resolution of 1 millisecond, round towards
1511 infinity to wait at least timeout seconds. */
1512 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
1513 _PyTime_ROUND_CEILING) < 0) {
1514 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1515 PyErr_SetString(PyExc_TypeError,
1516 "timeout must be an integer or None");
1517 }
1518 return NULL;
1519 }
1520
1521 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1522 if (ms < INT_MIN || ms > INT_MAX) {
1523 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
1524 return NULL;
1525 }
1526
1527 deadline = _PyTime_GetMonotonicClock() + timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001528 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001529
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001530 if (maxevents == -1) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001531 maxevents = FD_SETSIZE-1;
1532 }
1533 else if (maxevents < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001534 PyErr_Format(PyExc_ValueError,
1535 "maxevents must be greater than 0, got %d",
1536 maxevents);
1537 return NULL;
1538 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001539
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001540 evs = PyMem_New(struct epoll_event, maxevents);
1541 if (evs == NULL) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001542 PyErr_NoMemory();
1543 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001544 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001545
Victor Stinner41eba222015-03-30 21:59:21 +02001546 do {
1547 Py_BEGIN_ALLOW_THREADS
1548 errno = 0;
1549 nfds = epoll_wait(self->epfd, evs, maxevents, (int)ms);
1550 Py_END_ALLOW_THREADS
1551
1552 if (errno != EINTR)
1553 break;
1554
1555 /* poll() was interrupted by a signal */
1556 if (PyErr_CheckSignals())
1557 goto error;
1558
1559 if (timeout >= 0) {
1560 timeout = deadline - _PyTime_GetMonotonicClock();
1561 if (timeout < 0) {
1562 nfds = 0;
1563 break;
1564 }
1565 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1566 /* retry epoll_wait() with the recomputed timeout */
1567 }
1568 } while(1);
1569
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001570 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001571 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001572 goto error;
1573 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001574
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001575 elist = PyList_New(nfds);
1576 if (elist == NULL) {
1577 goto error;
1578 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001579
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001580 for (i = 0; i < nfds; i++) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001581 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001582 if (etuple == NULL) {
1583 Py_CLEAR(elist);
1584 goto error;
1585 }
1586 PyList_SET_ITEM(elist, i, etuple);
1587 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001588
Christian Heimesf6cd9672008-03-26 13:45:42 +00001589 error:
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001590 PyMem_Free(evs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001591 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001592}
1593
1594PyDoc_STRVAR(pyepoll_poll_doc,
1595"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1596\n\
1597Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1598in seconds (as float). -1 makes poll wait indefinitely.\n\
1599Up to maxevents are returned to the caller.");
1600
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001601static PyObject *
1602pyepoll_enter(pyEpoll_Object *self, PyObject *args)
1603{
1604 if (self->epfd < 0)
1605 return pyepoll_err_closed();
1606
1607 Py_INCREF(self);
1608 return (PyObject *)self;
1609}
1610
1611static PyObject *
1612pyepoll_exit(PyObject *self, PyObject *args)
1613{
1614 _Py_IDENTIFIER(close);
1615
1616 return _PyObject_CallMethodId(self, &PyId_close, NULL);
1617}
1618
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001619static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001620 {"fromfd", (PyCFunction)pyepoll_fromfd,
1621 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1622 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1623 pyepoll_close_doc},
1624 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1625 pyepoll_fileno_doc},
1626 {"modify", (PyCFunction)pyepoll_modify,
1627 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1628 {"register", (PyCFunction)pyepoll_register,
1629 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1630 {"unregister", (PyCFunction)pyepoll_unregister,
1631 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1632 {"poll", (PyCFunction)pyepoll_poll,
1633 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001634 {"__enter__", (PyCFunction)pyepoll_enter, METH_NOARGS,
1635 NULL},
1636 {"__exit__", (PyCFunction)pyepoll_exit, METH_VARARGS,
1637 NULL},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001638 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001639};
1640
1641static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001642 {"closed", (getter)pyepoll_get_closed, NULL,
1643 "True if the epoll handler is closed"},
1644 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001645};
1646
1647PyDoc_STRVAR(pyepoll_doc,
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001648"select.epoll(sizehint=-1, flags=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001649\n\
1650Returns an epolling object\n\
1651\n\
1652sizehint must be a positive integer or -1 for the default size. The\n\
1653sizehint is used to optimize internal data structures. It doesn't limit\n\
1654the maximum number of monitored events.");
1655
1656static PyTypeObject pyEpoll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001657 PyVarObject_HEAD_INIT(NULL, 0)
1658 "select.epoll", /* tp_name */
1659 sizeof(pyEpoll_Object), /* tp_basicsize */
1660 0, /* tp_itemsize */
1661 (destructor)pyepoll_dealloc, /* tp_dealloc */
1662 0, /* tp_print */
1663 0, /* tp_getattr */
1664 0, /* tp_setattr */
1665 0, /* tp_reserved */
1666 0, /* tp_repr */
1667 0, /* tp_as_number */
1668 0, /* tp_as_sequence */
1669 0, /* tp_as_mapping */
1670 0, /* tp_hash */
1671 0, /* tp_call */
1672 0, /* tp_str */
1673 PyObject_GenericGetAttr, /* tp_getattro */
1674 0, /* tp_setattro */
1675 0, /* tp_as_buffer */
1676 Py_TPFLAGS_DEFAULT, /* tp_flags */
1677 pyepoll_doc, /* tp_doc */
1678 0, /* tp_traverse */
1679 0, /* tp_clear */
1680 0, /* tp_richcompare */
1681 0, /* tp_weaklistoffset */
1682 0, /* tp_iter */
1683 0, /* tp_iternext */
1684 pyepoll_methods, /* tp_methods */
1685 0, /* tp_members */
1686 pyepoll_getsetlist, /* tp_getset */
1687 0, /* tp_base */
1688 0, /* tp_dict */
1689 0, /* tp_descr_get */
1690 0, /* tp_descr_set */
1691 0, /* tp_dictoffset */
1692 0, /* tp_init */
1693 0, /* tp_alloc */
1694 pyepoll_new, /* tp_new */
1695 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001696};
1697
1698#endif /* HAVE_EPOLL */
1699
1700#ifdef HAVE_KQUEUE
1701/* **************************************************************************
1702 * kqueue interface for BSD
1703 *
1704 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1705 * All rights reserved.
1706 *
1707 * Redistribution and use in source and binary forms, with or without
1708 * modification, are permitted provided that the following conditions
1709 * are met:
1710 * 1. Redistributions of source code must retain the above copyright
1711 * notice, this list of conditions and the following disclaimer.
1712 * 2. Redistributions in binary form must reproduce the above copyright
1713 * notice, this list of conditions and the following disclaimer in the
1714 * documentation and/or other materials provided with the distribution.
1715 *
1716 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1717 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1718 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1719 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1720 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1721 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1722 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1723 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1724 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1725 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1726 * SUCH DAMAGE.
1727 */
1728
1729#ifdef HAVE_SYS_EVENT_H
1730#include <sys/event.h>
1731#endif
1732
1733PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001734"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001735\n\
1736This object is the equivalent of the struct kevent for the C API.\n\
1737\n\
1738See the kqueue manpage for more detailed information about the meaning\n\
1739of the arguments.\n\
1740\n\
1741One minor note: while you might hope that udata could store a\n\
1742reference to a python object, it cannot, because it is impossible to\n\
1743keep a proper reference count of the object once it's passed into the\n\
1744kernel. Therefore, I have restricted it to only storing an integer. I\n\
1745recommend ignoring it and simply using the 'ident' field to key off\n\
1746of. You could also set up a dictionary on the python side to store a\n\
1747udata->object mapping.");
1748
1749typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001750 PyObject_HEAD
1751 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001752} kqueue_event_Object;
1753
1754static PyTypeObject kqueue_event_Type;
1755
1756#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1757
1758typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001759 PyObject_HEAD
1760 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001761} kqueue_queue_Object;
1762
1763static PyTypeObject kqueue_queue_Type;
1764
1765#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1766
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001767#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1768# error uintptr_t does not match void *!
1769#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1770# define T_UINTPTRT T_ULONGLONG
1771# define T_INTPTRT T_LONGLONG
1772# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1773# define UINTPTRT_FMT_UNIT "K"
1774# define INTPTRT_FMT_UNIT "L"
1775#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1776# define T_UINTPTRT T_ULONG
1777# define T_INTPTRT T_LONG
1778# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1779# define UINTPTRT_FMT_UNIT "k"
1780# define INTPTRT_FMT_UNIT "l"
1781#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1782# define T_UINTPTRT T_UINT
1783# define T_INTPTRT T_INT
1784# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1785# define UINTPTRT_FMT_UNIT "I"
1786# define INTPTRT_FMT_UNIT "i"
1787#else
1788# error uintptr_t does not match int, long, or long long!
1789#endif
1790
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001791/*
1792 * kevent is not standard and its members vary across BSDs.
1793 */
1794#if !defined(__OpenBSD__)
Christian Heimesaf01f662013-12-21 16:19:10 +01001795# define IDENT_TYPE T_UINTPTRT
1796# define IDENT_CAST Py_intptr_t
1797# define DATA_TYPE T_INTPTRT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001798# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
Christian Heimesaf01f662013-12-21 16:19:10 +01001799# define IDENT_AsType PyLong_AsUintptr_t
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001800#else
Christian Heimesaf01f662013-12-21 16:19:10 +01001801# define IDENT_TYPE T_UINT
1802# define IDENT_CAST int
1803# define DATA_TYPE T_INT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001804# define DATA_FMT_UNIT "i"
Christian Heimesaf01f662013-12-21 16:19:10 +01001805# define IDENT_AsType PyLong_AsUnsignedLong
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001806#endif
1807
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001808/* Unfortunately, we can't store python objects in udata, because
1809 * kevents in the kernel can be removed without warning, which would
1810 * forever lose the refcount on the object stored with it.
1811 */
1812
1813#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1814static struct PyMemberDef kqueue_event_members[] = {
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001815 {"ident", IDENT_TYPE, KQ_OFF(e.ident)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001816 {"filter", T_SHORT, KQ_OFF(e.filter)},
1817 {"flags", T_USHORT, KQ_OFF(e.flags)},
1818 {"fflags", T_UINT, KQ_OFF(e.fflags)},
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001819 {"data", DATA_TYPE, KQ_OFF(e.data)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001820 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1821 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001822};
1823#undef KQ_OFF
1824
1825static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001826
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001827kqueue_event_repr(kqueue_event_Object *s)
1828{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001829 char buf[1024];
1830 PyOS_snprintf(
1831 buf, sizeof(buf),
1832 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1833 "data=0x%zd udata=%p>",
1834 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1835 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1836 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001837}
1838
1839static int
1840kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1841{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001842 PyObject *pfd;
1843 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1844 "data", "udata", NULL};
Christian Heimesf1fe1592013-08-25 14:57:00 +02001845 static char *fmt = "O|hHI" DATA_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001846
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001847 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001848
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001849 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1850 &pfd, &(self->e.filter), &(self->e.flags),
1851 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1852 return -1;
1853 }
1854
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001855 if (PyLong_Check(pfd)
1856#if IDENT_TYPE == T_UINT
Christian Heimesaf01f662013-12-21 16:19:10 +01001857 && PyLong_AsUnsignedLong(pfd) <= UINT_MAX
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001858#endif
1859 ) {
1860 self->e.ident = IDENT_AsType(pfd);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001861 }
1862 else {
1863 self->e.ident = PyObject_AsFileDescriptor(pfd);
1864 }
1865 if (PyErr_Occurred()) {
1866 return -1;
1867 }
1868 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001869}
1870
1871static PyObject *
1872kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001873 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001874{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001875 Py_intptr_t result = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001876
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001877 if (!kqueue_event_Check(o)) {
1878 if (op == Py_EQ || op == Py_NE) {
1879 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1880 Py_INCREF(res);
1881 return res;
1882 }
1883 PyErr_Format(PyExc_TypeError,
1884 "can't compare %.200s to %.200s",
1885 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1886 return NULL;
1887 }
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001888 if (((result = (IDENT_CAST)(s->e.ident - o->e.ident)) == 0) &&
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001889 ((result = s->e.filter - o->e.filter) == 0) &&
1890 ((result = s->e.flags - o->e.flags) == 0) &&
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001891 ((result = (int)(s->e.fflags - o->e.fflags)) == 0) &&
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001892 ((result = s->e.data - o->e.data) == 0) &&
1893 ((result = s->e.udata - o->e.udata) == 0)
1894 ) {
1895 result = 0;
1896 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001897
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001898 switch (op) {
Guido van Rossumee07b942013-12-06 17:46:22 -08001899 case Py_EQ:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001900 result = (result == 0);
1901 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001902 case Py_NE:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001903 result = (result != 0);
1904 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001905 case Py_LE:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001906 result = (result <= 0);
1907 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001908 case Py_GE:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001909 result = (result >= 0);
1910 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001911 case Py_LT:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001912 result = (result < 0);
1913 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001914 case Py_GT:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001915 result = (result > 0);
1916 break;
1917 }
1918 return PyBool_FromLong((long)result);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001919}
1920
1921static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001922 PyVarObject_HEAD_INIT(NULL, 0)
1923 "select.kevent", /* tp_name */
1924 sizeof(kqueue_event_Object), /* tp_basicsize */
1925 0, /* tp_itemsize */
1926 0, /* tp_dealloc */
1927 0, /* tp_print */
1928 0, /* tp_getattr */
1929 0, /* tp_setattr */
1930 0, /* tp_reserved */
1931 (reprfunc)kqueue_event_repr, /* tp_repr */
1932 0, /* tp_as_number */
1933 0, /* tp_as_sequence */
1934 0, /* tp_as_mapping */
1935 0, /* tp_hash */
1936 0, /* tp_call */
1937 0, /* tp_str */
1938 0, /* tp_getattro */
1939 0, /* tp_setattro */
1940 0, /* tp_as_buffer */
1941 Py_TPFLAGS_DEFAULT, /* tp_flags */
1942 kqueue_event_doc, /* tp_doc */
1943 0, /* tp_traverse */
1944 0, /* tp_clear */
1945 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1946 0, /* tp_weaklistoffset */
1947 0, /* tp_iter */
1948 0, /* tp_iternext */
1949 0, /* tp_methods */
1950 kqueue_event_members, /* tp_members */
1951 0, /* tp_getset */
1952 0, /* tp_base */
1953 0, /* tp_dict */
1954 0, /* tp_descr_get */
1955 0, /* tp_descr_set */
1956 0, /* tp_dictoffset */
1957 (initproc)kqueue_event_init, /* tp_init */
1958 0, /* tp_alloc */
1959 0, /* tp_new */
1960 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001961};
1962
1963static PyObject *
1964kqueue_queue_err_closed(void)
1965{
Victor Stinner13423c32013-08-22 00:19:50 +02001966 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001967 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001968}
1969
1970static int
1971kqueue_queue_internal_close(kqueue_queue_Object *self)
1972{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001973 int save_errno = 0;
1974 if (self->kqfd >= 0) {
1975 int kqfd = self->kqfd;
1976 self->kqfd = -1;
1977 Py_BEGIN_ALLOW_THREADS
1978 if (close(kqfd) < 0)
1979 save_errno = errno;
1980 Py_END_ALLOW_THREADS
1981 }
1982 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001983}
1984
1985static PyObject *
1986newKqueue_Object(PyTypeObject *type, SOCKET fd)
1987{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001988 kqueue_queue_Object *self;
1989 assert(type != NULL && type->tp_alloc != NULL);
1990 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1991 if (self == NULL) {
1992 return NULL;
1993 }
1994
1995 if (fd == -1) {
1996 Py_BEGIN_ALLOW_THREADS
1997 self->kqfd = kqueue();
1998 Py_END_ALLOW_THREADS
1999 }
2000 else {
2001 self->kqfd = fd;
2002 }
2003 if (self->kqfd < 0) {
2004 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002005 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002006 return NULL;
2007 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02002008
2009 if (fd == -1) {
2010 if (_Py_set_inheritable(self->kqfd, 0, NULL) < 0) {
2011 Py_DECREF(self);
2012 return NULL;
2013 }
2014 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002015 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002016}
2017
2018static PyObject *
2019kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2020{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002021 if ((args != NULL && PyObject_Size(args)) ||
2022 (kwds != NULL && PyObject_Size(kwds))) {
2023 PyErr_SetString(PyExc_ValueError,
2024 "select.kqueue doesn't accept arguments");
2025 return NULL;
2026 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002027
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002028 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002029}
2030
2031static void
2032kqueue_queue_dealloc(kqueue_queue_Object *self)
2033{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002034 kqueue_queue_internal_close(self);
2035 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002036}
2037
2038static PyObject*
2039kqueue_queue_close(kqueue_queue_Object *self)
2040{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002041 errno = kqueue_queue_internal_close(self);
2042 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002043 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002044 return NULL;
2045 }
2046 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002047}
2048
2049PyDoc_STRVAR(kqueue_queue_close_doc,
2050"close() -> None\n\
2051\n\
2052Close the kqueue control file descriptor. Further operations on the kqueue\n\
2053object will raise an exception.");
2054
2055static PyObject*
2056kqueue_queue_get_closed(kqueue_queue_Object *self)
2057{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002058 if (self->kqfd < 0)
2059 Py_RETURN_TRUE;
2060 else
2061 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002062}
2063
2064static PyObject*
2065kqueue_queue_fileno(kqueue_queue_Object *self)
2066{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002067 if (self->kqfd < 0)
2068 return kqueue_queue_err_closed();
2069 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002070}
2071
2072PyDoc_STRVAR(kqueue_queue_fileno_doc,
2073"fileno() -> int\n\
2074\n\
2075Return the kqueue control file descriptor.");
2076
2077static PyObject*
2078kqueue_queue_fromfd(PyObject *cls, PyObject *args)
2079{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002080 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002081
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002082 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
2083 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002084
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002085 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002086}
2087
2088PyDoc_STRVAR(kqueue_queue_fromfd_doc,
2089"fromfd(fd) -> kqueue\n\
2090\n\
2091Create a kqueue object from a given control fd.");
2092
2093static PyObject *
2094kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
2095{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002096 int nevents = 0;
2097 int gotevents = 0;
2098 int nchanges = 0;
2099 int i = 0;
2100 PyObject *otimeout = NULL;
2101 PyObject *ch = NULL;
2102 PyObject *it = NULL, *ei = NULL;
2103 PyObject *result = NULL;
2104 struct kevent *evl = NULL;
2105 struct kevent *chl = NULL;
Victor Stinner4448c082015-03-31 11:48:34 +02002106 struct timespec timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002107 struct timespec *ptimeoutspec;
Victor Stinner4448c082015-03-31 11:48:34 +02002108 _PyTime_t timeout, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002109
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002110 if (self->kqfd < 0)
2111 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002112
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002113 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
2114 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002115
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002116 if (nevents < 0) {
2117 PyErr_Format(PyExc_ValueError,
2118 "Length of eventlist must be 0 or positive, got %d",
2119 nevents);
2120 return NULL;
2121 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002123 if (otimeout == Py_None || otimeout == NULL) {
2124 ptimeoutspec = NULL;
2125 }
Victor Stinnerc3378382015-03-28 05:07:51 +01002126 else {
Victor Stinner4448c082015-03-31 11:48:34 +02002127 if (_PyTime_FromSecondsObject(&timeout,
Victor Stinner869e1772015-03-30 03:49:14 +02002128 otimeout, _PyTime_ROUND_CEILING) < 0) {
Victor Stinnerc3378382015-03-28 05:07:51 +01002129 PyErr_Format(PyExc_TypeError,
2130 "timeout argument must be an number "
2131 "or None, got %.200s",
2132 Py_TYPE(otimeout)->tp_name);
2133 return NULL;
2134 }
2135
Victor Stinner4448c082015-03-31 11:48:34 +02002136 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
Victor Stinner5d272cc2012-03-13 13:35:55 +01002137 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002138
Victor Stinner4448c082015-03-31 11:48:34 +02002139 if (timeoutspec.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002140 PyErr_SetString(PyExc_ValueError,
2141 "timeout must be positive or None");
2142 return NULL;
2143 }
Victor Stinner4448c082015-03-31 11:48:34 +02002144 ptimeoutspec = &timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002145 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002146
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002147 if (ch != NULL && ch != Py_None) {
2148 it = PyObject_GetIter(ch);
2149 if (it == NULL) {
2150 PyErr_SetString(PyExc_TypeError,
2151 "changelist is not iterable");
2152 return NULL;
2153 }
2154 nchanges = PyObject_Size(ch);
2155 if (nchanges < 0) {
2156 goto error;
2157 }
Georg Brandlc0e22b72010-03-14 10:51:01 +00002158
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002159 chl = PyMem_New(struct kevent, nchanges);
2160 if (chl == NULL) {
2161 PyErr_NoMemory();
2162 goto error;
2163 }
2164 i = 0;
2165 while ((ei = PyIter_Next(it)) != NULL) {
2166 if (!kqueue_event_Check(ei)) {
2167 Py_DECREF(ei);
2168 PyErr_SetString(PyExc_TypeError,
2169 "changelist must be an iterable of "
2170 "select.kevent objects");
2171 goto error;
2172 } else {
2173 chl[i++] = ((kqueue_event_Object *)ei)->e;
2174 }
2175 Py_DECREF(ei);
2176 }
2177 }
2178 Py_CLEAR(it);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002179
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002180 /* event list */
2181 if (nevents) {
2182 evl = PyMem_New(struct kevent, nevents);
2183 if (evl == NULL) {
2184 PyErr_NoMemory();
2185 goto error;
2186 }
2187 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002188
Victor Stinner4448c082015-03-31 11:48:34 +02002189 if (ptimeoutspec)
2190 deadline = _PyTime_GetMonotonicClock() + timeout;
2191
2192 do {
2193 Py_BEGIN_ALLOW_THREADS
2194 errno = 0;
2195 gotevents = kevent(self->kqfd, chl, nchanges,
2196 evl, nevents, ptimeoutspec);
2197 Py_END_ALLOW_THREADS
2198
2199 if (errno != EINTR)
2200 break;
2201
2202 /* kevent() was interrupted by a signal */
2203 if (PyErr_CheckSignals())
2204 goto error;
2205
2206 if (ptimeoutspec) {
2207 timeout = deadline - _PyTime_GetMonotonicClock();
2208 if (timeout < 0) {
2209 gotevents = 0;
2210 break;
2211 }
2212 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
2213 goto error;
2214 /* retry kevent() with the recomputed timeout */
2215 }
2216 } while (1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002217
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002218 if (gotevents == -1) {
2219 PyErr_SetFromErrno(PyExc_OSError);
2220 goto error;
2221 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002222
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002223 result = PyList_New(gotevents);
2224 if (result == NULL) {
2225 goto error;
2226 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002228 for (i = 0; i < gotevents; i++) {
2229 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002231 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
2232 if (ch == NULL) {
2233 goto error;
2234 }
2235 ch->e = evl[i];
2236 PyList_SET_ITEM(result, i, (PyObject *)ch);
2237 }
2238 PyMem_Free(chl);
2239 PyMem_Free(evl);
2240 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002241
2242 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002243 PyMem_Free(chl);
2244 PyMem_Free(evl);
2245 Py_XDECREF(result);
2246 Py_XDECREF(it);
2247 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002248}
2249
2250PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00002251"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002252\n\
2253Calls the kernel kevent function.\n\
2254- changelist must be a list of kevent objects describing the changes\n\
2255 to be made to the kernel's watch list or None.\n\
2256- max_events lets you specify the maximum number of events that the\n\
2257 kernel will return.\n\
2258- timeout is the maximum time to wait in seconds, or else None,\n\
2259 to wait forever. timeout accepts floats for smaller timeouts, too.");
2260
2261
2262static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002263 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
2264 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
2265 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
2266 kqueue_queue_close_doc},
2267 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
2268 kqueue_queue_fileno_doc},
2269 {"control", (PyCFunction)kqueue_queue_control,
2270 METH_VARARGS , kqueue_queue_control_doc},
2271 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002272};
2273
2274static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002275 {"closed", (getter)kqueue_queue_get_closed, NULL,
2276 "True if the kqueue handler is closed"},
2277 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002278};
2279
2280PyDoc_STRVAR(kqueue_queue_doc,
2281"Kqueue syscall wrapper.\n\
2282\n\
2283For example, to start watching a socket for input:\n\
2284>>> kq = kqueue()\n\
2285>>> sock = socket()\n\
2286>>> sock.connect((host, port))\n\
2287>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
2288\n\
2289To wait one second for it to become writeable:\n\
2290>>> kq.control(None, 1, 1000)\n\
2291\n\
2292To stop listening:\n\
2293>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
2294
2295static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002296 PyVarObject_HEAD_INIT(NULL, 0)
2297 "select.kqueue", /* tp_name */
2298 sizeof(kqueue_queue_Object), /* tp_basicsize */
2299 0, /* tp_itemsize */
2300 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
2301 0, /* tp_print */
2302 0, /* tp_getattr */
2303 0, /* tp_setattr */
2304 0, /* tp_reserved */
2305 0, /* tp_repr */
2306 0, /* tp_as_number */
2307 0, /* tp_as_sequence */
2308 0, /* tp_as_mapping */
2309 0, /* tp_hash */
2310 0, /* tp_call */
2311 0, /* tp_str */
2312 0, /* tp_getattro */
2313 0, /* tp_setattro */
2314 0, /* tp_as_buffer */
2315 Py_TPFLAGS_DEFAULT, /* tp_flags */
2316 kqueue_queue_doc, /* tp_doc */
2317 0, /* tp_traverse */
2318 0, /* tp_clear */
2319 0, /* tp_richcompare */
2320 0, /* tp_weaklistoffset */
2321 0, /* tp_iter */
2322 0, /* tp_iternext */
2323 kqueue_queue_methods, /* tp_methods */
2324 0, /* tp_members */
2325 kqueue_queue_getsetlist, /* tp_getset */
2326 0, /* tp_base */
2327 0, /* tp_dict */
2328 0, /* tp_descr_get */
2329 0, /* tp_descr_set */
2330 0, /* tp_dictoffset */
2331 0, /* tp_init */
2332 0, /* tp_alloc */
2333 kqueue_queue_new, /* tp_new */
2334 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002335};
2336
2337#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002338
2339
2340
2341
2342
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002343/* ************************************************************************ */
2344
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002345PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002346"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
2347\n\
2348Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00002349The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002350rlist -- wait until ready for reading\n\
2351wlist -- wait until ready for writing\n\
2352xlist -- wait for an ``exceptional condition''\n\
2353If only one kind of condition is required, pass [] for the other lists.\n\
2354A file descriptor is either a socket or file object, or a small integer\n\
2355gotten from a fileno() method call on one of those.\n\
2356\n\
2357The optional 4th argument specifies a timeout in seconds; it may be\n\
2358a floating point number to specify fractions of seconds. If it is absent\n\
2359or None, the call will never time out.\n\
2360\n\
2361The return value is a tuple of three lists corresponding to the first three\n\
2362arguments; each contains the subset of the corresponding file descriptors\n\
2363that are ready.\n\
2364\n\
2365*** IMPORTANT NOTICE ***\n\
Christian Heimesaf01f662013-12-21 16:19:10 +01002366On Windows only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00002367descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002368
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002369static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002370 {"select", select_select, METH_VARARGS, select_doc},
Charles-François Natali986a56c2013-01-19 12:19:10 +01002371#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002372 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00002373#endif /* HAVE_POLL */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002374#ifdef HAVE_SYS_DEVPOLL_H
2375 {"devpoll", select_devpoll, METH_NOARGS, devpoll_doc},
2376#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002377 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002378};
2379
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002380PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002381"This module supports asynchronous I/O on multiple file descriptors.\n\
2382\n\
2383*** IMPORTANT NOTICE ***\n\
Christian Heimesaf01f662013-12-21 16:19:10 +01002384On Windows only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002385
Martin v. Löwis1a214512008-06-11 05:26:20 +00002386
2387static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002388 PyModuleDef_HEAD_INIT,
2389 "select",
2390 module_doc,
2391 -1,
2392 select_methods,
2393 NULL,
2394 NULL,
2395 NULL,
2396 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002397};
2398
Jesus Cead8b9ae62011-11-14 19:07:41 +01002399
2400
2401
Mark Hammond62b1ab12002-07-23 06:31:15 +00002402PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002403PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002404{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002405 PyObject *m;
2406 m = PyModule_Create(&selectmodule);
2407 if (m == NULL)
2408 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002409
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002410 Py_INCREF(PyExc_OSError);
2411 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002412
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002413#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002414#ifdef HAVE_BROKEN_PIPE_BUF
2415#undef PIPE_BUF
2416#define PIPE_BUF 512
2417#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002418 PyModule_AddIntMacro(m, PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002419#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002420
Charles-François Natali986a56c2013-01-19 12:19:10 +01002421#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002422#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002423 if (select_have_broken_poll()) {
2424 if (PyObject_DelAttrString(m, "poll") == -1) {
2425 PyErr_Clear();
2426 }
2427 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002428#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002429 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002430#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002431 if (PyType_Ready(&poll_Type) < 0)
2432 return NULL;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002433 PyModule_AddIntMacro(m, POLLIN);
2434 PyModule_AddIntMacro(m, POLLPRI);
2435 PyModule_AddIntMacro(m, POLLOUT);
2436 PyModule_AddIntMacro(m, POLLERR);
2437 PyModule_AddIntMacro(m, POLLHUP);
2438 PyModule_AddIntMacro(m, POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002439
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002440#ifdef POLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002441 PyModule_AddIntMacro(m, POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002442#endif
2443#ifdef POLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002444 PyModule_AddIntMacro(m, POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002445#endif
2446#ifdef POLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002447 PyModule_AddIntMacro(m, POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002448#endif
2449#ifdef POLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002450 PyModule_AddIntMacro(m, POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002451#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002452#ifdef POLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002453 PyModule_AddIntMacro(m, POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002454#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002455 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002456#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002457
Jesus Cead8b9ae62011-11-14 19:07:41 +01002458#ifdef HAVE_SYS_DEVPOLL_H
2459 if (PyType_Ready(&devpoll_Type) < 0)
2460 return NULL;
2461#endif
2462
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002463#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002464 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
2465 if (PyType_Ready(&pyEpoll_Type) < 0)
2466 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002467
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002468 Py_INCREF(&pyEpoll_Type);
2469 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002470
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002471 PyModule_AddIntMacro(m, EPOLLIN);
2472 PyModule_AddIntMacro(m, EPOLLOUT);
2473 PyModule_AddIntMacro(m, EPOLLPRI);
2474 PyModule_AddIntMacro(m, EPOLLERR);
2475 PyModule_AddIntMacro(m, EPOLLHUP);
2476 PyModule_AddIntMacro(m, EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002477#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002478 /* Kernel 2.6.2+ */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002479 PyModule_AddIntMacro(m, EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002480#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002481 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
Zachary Ware3e776772015-08-01 21:34:05 -05002482
2483#ifdef EPOLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002484 PyModule_AddIntMacro(m, EPOLLRDNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002485#endif
2486#ifdef EPOLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002487 PyModule_AddIntMacro(m, EPOLLRDBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002488#endif
2489#ifdef EPOLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002490 PyModule_AddIntMacro(m, EPOLLWRNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002491#endif
2492#ifdef EPOLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002493 PyModule_AddIntMacro(m, EPOLLWRBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002494#endif
2495#ifdef EPOLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002496 PyModule_AddIntMacro(m, EPOLLMSG);
Zachary Ware3e776772015-08-01 21:34:05 -05002497#endif
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002498
Benjamin Peterson95c16622011-12-27 15:36:32 -06002499#ifdef EPOLL_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002500 PyModule_AddIntMacro(m, EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002501#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002502#endif /* HAVE_EPOLL */
2503
2504#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002505 kqueue_event_Type.tp_new = PyType_GenericNew;
2506 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
2507 if(PyType_Ready(&kqueue_event_Type) < 0)
2508 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002509
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002510 Py_INCREF(&kqueue_event_Type);
2511 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002513 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
2514 if(PyType_Ready(&kqueue_queue_Type) < 0)
2515 return NULL;
2516 Py_INCREF(&kqueue_queue_Type);
2517 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
2518
2519 /* event filters */
2520 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2521 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
2522 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
2523 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
2524 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002525#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002526 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002527#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002528 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
2529 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002530
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002531 /* event flags */
2532 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2533 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2534 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2535 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2536 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2537 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002538
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002539 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
2540 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002541
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002542 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2543 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002544
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002545 /* READ WRITE filter flag */
2546 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002547
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002548 /* VNODE filter flags */
2549 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2550 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2551 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2552 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2553 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2554 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2555 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002556
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002557 /* PROC filter flags */
2558 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2559 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2560 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2561 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2562 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002563
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002564 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2565 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2566 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
2567
2568 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002569#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002570 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2571 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2572 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002573#endif
2574
2575#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002576 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002577}