~ubuntu-branches/ubuntu/maverick/python3.1/maverick

« back to all changes in this revision

Viewing changes to Modules/selectmodule.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-03-23 00:01:27 UTC
  • Revision ID: james.westby@ubuntu.com-20090323000127-5fstfxju4ufrhthq
Tags: upstream-3.1~a1+20090322
ImportĀ upstreamĀ versionĀ 3.1~a1+20090322

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* select - Module containing unix select(2) call.
 
2
   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.
 
5
*/
 
6
 
 
7
#include "Python.h"
 
8
#include <structmember.h>
 
9
 
 
10
#ifdef __APPLE__
 
11
    /* Perform runtime testing for a broken poll on OSX to make it easier
 
12
     * to use the same binary on multiple releases of the OS.
 
13
     */
 
14
#undef HAVE_BROKEN_POLL
 
15
#endif
 
16
 
 
17
/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
 
18
   64 is too small (too many people have bumped into that limit).
 
19
   Here we boost it.
 
20
   Users who want even more than the boosted limit should #define
 
21
   FD_SETSIZE higher before this; e.g., via compiler /D switch.
 
22
*/
 
23
#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
 
24
#define FD_SETSIZE 512
 
25
#endif 
 
26
 
 
27
#if defined(HAVE_POLL_H)
 
28
#include <poll.h>
 
29
#elif defined(HAVE_SYS_POLL_H)
 
30
#include <sys/poll.h>
 
31
#endif
 
32
 
 
33
#ifdef __sgi
 
34
/* This is missing from unistd.h */
 
35
extern void bzero(void *, int);
 
36
#endif
 
37
 
 
38
#ifdef HAVE_SYS_TYPES_H
 
39
#include <sys/types.h>
 
40
#endif
 
41
 
 
42
#if defined(PYOS_OS2) && !defined(PYCC_GCC)
 
43
#include <sys/time.h>
 
44
#include <utils.h>
 
45
#endif
 
46
 
 
47
#ifdef MS_WINDOWS
 
48
#  define WIN32_LEAN_AND_MEAN
 
49
#  include <winsock.h>
 
50
#else
 
51
#  define SOCKET int
 
52
#  if defined(__VMS)
 
53
#    include <socket.h>
 
54
#  endif
 
55
#endif
 
56
 
 
57
static PyObject *SelectError;
 
58
 
 
59
/* list of Python objects and their file descriptor */
 
60
typedef struct {
 
61
        PyObject *obj;                       /* owned reference */
 
62
        SOCKET fd;
 
63
        int sentinel;                        /* -1 == sentinel */
 
64
} pylist;
 
65
 
 
66
static void
 
67
reap_obj(pylist fd2obj[FD_SETSIZE + 1])
 
68
{
 
69
        int i;
 
70
        for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
 
71
                Py_XDECREF(fd2obj[i].obj);
 
72
                fd2obj[i].obj = NULL;
 
73
        }
 
74
        fd2obj[0].sentinel = -1;
 
75
}
 
76
 
 
77
 
 
78
/* returns -1 and sets the Python exception if an error occurred, otherwise
 
79
   returns a number >= 0
 
80
*/
 
81
static int
 
82
seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
 
83
{
 
84
        int i;
 
85
        int max = -1;
 
86
        int index = 0;
 
87
        int len = -1;
 
88
        PyObject* fast_seq = NULL;
 
89
        PyObject* o = NULL;
 
90
 
 
91
        fd2obj[0].obj = (PyObject*)0;        /* set list to zero size */
 
92
        FD_ZERO(set);
 
93
 
 
94
        fast_seq=PySequence_Fast(seq, "arguments 1-3 must be sequences");
 
95
        if (!fast_seq)
 
96
            return -1;
 
97
 
 
98
        len = PySequence_Fast_GET_SIZE(fast_seq);
 
99
 
 
100
        for (i = 0; i < len; i++)  {
 
101
                SOCKET v;
 
102
 
 
103
                /* any intervening fileno() calls could decr this refcnt */
 
104
                if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
 
105
                    return -1;
 
106
 
 
107
                Py_INCREF(o);
 
108
                v = PyObject_AsFileDescriptor( o );
 
109
                if (v == -1) goto finally;
 
110
 
 
111
#if defined(_MSC_VER)
 
112
                max = 0;                     /* not used for Win32 */
 
113
#else  /* !_MSC_VER */
 
114
                if (v < 0 || v >= FD_SETSIZE) {
 
115
                        PyErr_SetString(PyExc_ValueError,
 
116
                                    "filedescriptor out of range in select()");
 
117
                        goto finally;
 
118
                }
 
119
                if (v > max)
 
120
                        max = v;
 
121
#endif /* _MSC_VER */
 
122
                FD_SET(v, set);
 
123
 
 
124
                /* add object and its file descriptor to the list */
 
125
                if (index >= FD_SETSIZE) {
 
126
                        PyErr_SetString(PyExc_ValueError,
 
127
                                      "too many file descriptors in select()");
 
128
                        goto finally;
 
129
                }
 
130
                fd2obj[index].obj = o;
 
131
                fd2obj[index].fd = v;
 
132
                fd2obj[index].sentinel = 0;
 
133
                fd2obj[++index].sentinel = -1;
 
134
        }
 
135
        Py_DECREF(fast_seq);
 
136
        return max+1;
 
137
 
 
138
  finally:
 
139
        Py_XDECREF(o);
 
140
        Py_DECREF(fast_seq);
 
141
        return -1;
 
142
}
 
143
 
 
144
/* returns NULL and sets the Python exception if an error occurred */
 
145
static PyObject *
 
146
set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
 
147
{
 
148
        int i, j, count=0;
 
149
        PyObject *list, *o;
 
150
        SOCKET fd;
 
151
 
 
152
        for (j = 0; fd2obj[j].sentinel >= 0; j++) {
 
153
                if (FD_ISSET(fd2obj[j].fd, set))
 
154
                        count++;
 
155
        }
 
156
        list = PyList_New(count);
 
157
        if (!list)
 
158
                return NULL;
 
159
 
 
160
        i = 0;
 
161
        for (j = 0; fd2obj[j].sentinel >= 0; j++) {
 
162
                fd = fd2obj[j].fd;
 
163
                if (FD_ISSET(fd, set)) {
 
164
#ifndef _MSC_VER
 
165
                        if (fd > FD_SETSIZE) {
 
166
                                PyErr_SetString(PyExc_SystemError,
 
167
                           "filedescriptor out of range returned in select()");
 
168
                                goto finally;
 
169
                        }
 
170
#endif
 
171
                        o = fd2obj[j].obj;
 
172
                        fd2obj[j].obj = NULL;
 
173
                        /* transfer ownership */
 
174
                        if (PyList_SetItem(list, i, o) < 0)
 
175
                                goto finally;
 
176
 
 
177
                        i++;
 
178
                }
 
179
        }
 
180
        return list;
 
181
  finally:
 
182
        Py_DECREF(list);
 
183
        return NULL;
 
184
}
 
185
 
 
186
#undef SELECT_USES_HEAP
 
187
#if FD_SETSIZE > 1024
 
188
#define SELECT_USES_HEAP
 
189
#endif /* FD_SETSIZE > 1024 */
 
190
 
 
191
static PyObject *
 
192
select_select(PyObject *self, PyObject *args)
 
193
{
 
194
#ifdef SELECT_USES_HEAP
 
195
        pylist *rfd2obj, *wfd2obj, *efd2obj;
 
196
#else  /* !SELECT_USES_HEAP */
 
197
        /* XXX: All this should probably be implemented as follows:
 
198
         * - find the highest descriptor we're interested in
 
199
         * - add one
 
200
         * - that's the size
 
201
         * See: Stevens, APitUE, $12.5.1
 
202
         */
 
203
        pylist rfd2obj[FD_SETSIZE + 1];
 
204
        pylist wfd2obj[FD_SETSIZE + 1];
 
205
        pylist efd2obj[FD_SETSIZE + 1];
 
206
#endif /* SELECT_USES_HEAP */
 
207
        PyObject *ifdlist, *ofdlist, *efdlist;
 
208
        PyObject *ret = NULL;
 
209
        PyObject *tout = Py_None;
 
210
        fd_set ifdset, ofdset, efdset;
 
211
        double timeout;
 
212
        struct timeval tv, *tvp;
 
213
        long seconds;
 
214
        int imax, omax, emax, max;
 
215
        int n;
 
216
 
 
217
        /* convert arguments */
 
218
        if (!PyArg_UnpackTuple(args, "select", 3, 4,
 
219
                              &ifdlist, &ofdlist, &efdlist, &tout))
 
220
                return NULL;
 
221
 
 
222
        if (tout == Py_None)
 
223
                tvp = (struct timeval *)0;
 
224
        else if (!PyNumber_Check(tout)) {
 
225
                PyErr_SetString(PyExc_TypeError,
 
226
                                "timeout must be a float or None");
 
227
                return NULL;
 
228
        }
 
229
        else {
 
230
                timeout = PyFloat_AsDouble(tout);
 
231
                if (timeout == -1 && PyErr_Occurred())
 
232
                        return NULL;
 
233
                if (timeout > (double)LONG_MAX) {
 
234
                        PyErr_SetString(PyExc_OverflowError,
 
235
                                        "timeout period too long");
 
236
                        return NULL;
 
237
                }
 
238
                seconds = (long)timeout;
 
239
                timeout = timeout - (double)seconds;
 
240
                tv.tv_sec = seconds;
 
241
                tv.tv_usec = (long)(timeout * 1E6);
 
242
                tvp = &tv;
 
243
        }
 
244
 
 
245
 
 
246
#ifdef SELECT_USES_HEAP
 
247
        /* Allocate memory for the lists */
 
248
        rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
 
249
        wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
 
250
        efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
 
251
        if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
 
252
                if (rfd2obj) PyMem_DEL(rfd2obj);
 
253
                if (wfd2obj) PyMem_DEL(wfd2obj);
 
254
                if (efd2obj) PyMem_DEL(efd2obj);
 
255
                return PyErr_NoMemory();
 
256
        }
 
257
#endif /* SELECT_USES_HEAP */
 
258
        /* Convert sequences to fd_sets, and get maximum fd number
 
259
         * propagates the Python exception set in seq2set()
 
260
         */
 
261
        rfd2obj[0].sentinel = -1;
 
262
        wfd2obj[0].sentinel = -1;
 
263
        efd2obj[0].sentinel = -1;
 
264
        if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0) 
 
265
                goto finally;
 
266
        if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0) 
 
267
                goto finally;
 
268
        if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0) 
 
269
                goto finally;
 
270
        max = imax;
 
271
        if (omax > max) max = omax;
 
272
        if (emax > max) max = emax;
 
273
 
 
274
        Py_BEGIN_ALLOW_THREADS
 
275
        n = select(max, &ifdset, &ofdset, &efdset, tvp);
 
276
        Py_END_ALLOW_THREADS
 
277
 
 
278
#ifdef MS_WINDOWS
 
279
        if (n == SOCKET_ERROR) {
 
280
                PyErr_SetExcFromWindowsErr(SelectError, WSAGetLastError());
 
281
        }
 
282
#else
 
283
        if (n < 0) {
 
284
                PyErr_SetFromErrno(SelectError);
 
285
        }
 
286
#endif
 
287
        else if (n == 0) {
 
288
                /* optimization */
 
289
                ifdlist = PyList_New(0);
 
290
                if (ifdlist) {
 
291
                        ret = PyTuple_Pack(3, ifdlist, ifdlist, ifdlist);
 
292
                        Py_DECREF(ifdlist);
 
293
                }
 
294
        }
 
295
        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);
 
307
 
 
308
                Py_DECREF(ifdlist);
 
309
                Py_DECREF(ofdlist);
 
310
                Py_DECREF(efdlist);
 
311
        }
 
312
        
 
313
  finally:
 
314
        reap_obj(rfd2obj);
 
315
        reap_obj(wfd2obj);
 
316
        reap_obj(efd2obj);
 
317
#ifdef SELECT_USES_HEAP
 
318
        PyMem_DEL(rfd2obj);
 
319
        PyMem_DEL(wfd2obj);
 
320
        PyMem_DEL(efd2obj);
 
321
#endif /* SELECT_USES_HEAP */
 
322
        return ret;
 
323
}
 
324
 
 
325
#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
 
326
/* 
 
327
 * poll() support
 
328
 */
 
329
 
 
330
typedef struct {
 
331
        PyObject_HEAD
 
332
        PyObject *dict;
 
333
        int ufd_uptodate; 
 
334
        int ufd_len;
 
335
        struct pollfd *ufds;
 
336
} pollObject;
 
337
 
 
338
static PyTypeObject poll_Type;
 
339
 
 
340
/* Update the malloc'ed array of pollfds to match the dictionary 
 
341
   contained within a pollObject.  Return 1 on success, 0 on an error.
 
342
*/
 
343
 
 
344
static int
 
345
update_ufd_array(pollObject *self)
 
346
{
 
347
        Py_ssize_t i, pos;
 
348
        PyObject *key, *value;
 
349
        struct pollfd *old_ufds = self->ufds;
 
350
 
 
351
        self->ufd_len = PyDict_Size(self->dict);
 
352
        PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
 
353
        if (self->ufds == NULL) {
 
354
                self->ufds = old_ufds;
 
355
                PyErr_NoMemory();
 
356
                return 0;
 
357
        }
 
358
 
 
359
        i = pos = 0;
 
360
        while (PyDict_Next(self->dict, &pos, &key, &value)) {
 
361
                self->ufds[i].fd = PyLong_AsLong(key);
 
362
                self->ufds[i].events = (short)PyLong_AsLong(value);
 
363
                i++;
 
364
        }
 
365
        self->ufd_uptodate = 1;
 
366
        return 1;
 
367
}
 
368
 
 
369
PyDoc_STRVAR(poll_register_doc,
 
370
"register(fd [, eventmask] ) -> None\n\n\
 
371
Register a file descriptor with the polling object.\n\
 
372
fd -- either an integer, or an object with a fileno() method returning an\n\
 
373
      int.\n\
 
374
events -- an optional bitmask describing the type of events to check for");
 
375
 
 
376
static PyObject *
 
377
poll_register(pollObject *self, PyObject *args) 
 
378
{
 
379
        PyObject *o, *key, *value;
 
380
        int fd, events = POLLIN | POLLPRI | POLLOUT;
 
381
        int err;
 
382
 
 
383
        if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
 
384
                return NULL;
 
385
        }
 
386
  
 
387
        fd = PyObject_AsFileDescriptor(o);
 
388
        if (fd == -1) return NULL;
 
389
 
 
390
        /* Add entry to the internal dictionary: the key is the 
 
391
           file descriptor, and the value is the event mask. */
 
392
        key = PyLong_FromLong(fd);
 
393
        if (key == NULL)
 
394
                return NULL;
 
395
        value = PyLong_FromLong(events);
 
396
        if (value == NULL) {
 
397
                Py_DECREF(key);
 
398
                return NULL;
 
399
        }
 
400
        err = PyDict_SetItem(self->dict, key, value);
 
401
        Py_DECREF(key);
 
402
        Py_DECREF(value);
 
403
        if (err < 0)
 
404
                return NULL;
 
405
 
 
406
        self->ufd_uptodate = 0;
 
407
 
 
408
        Py_INCREF(Py_None);
 
409
        return Py_None;
 
410
}
 
411
 
 
412
PyDoc_STRVAR(poll_modify_doc,
 
413
"modify(fd, eventmask) -> None\n\n\
 
414
Modify an already registered file descriptor.\n\
 
415
fd -- either an integer, or an object with a fileno() method returning an\n\
 
416
      int.\n\
 
417
events -- an optional bitmask describing the type of events to check for");
 
418
 
 
419
static PyObject *
 
420
poll_modify(pollObject *self, PyObject *args)
 
421
{
 
422
        PyObject *o, *key, *value;
 
423
        int fd, events;
 
424
        int err;
 
425
 
 
426
        if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) {
 
427
                return NULL;
 
428
        }
 
429
  
 
430
        fd = PyObject_AsFileDescriptor(o);
 
431
        if (fd == -1) return NULL;
 
432
 
 
433
        /* Modify registered fd */
 
434
        key = PyLong_FromLong(fd);
 
435
        if (key == NULL)
 
436
                return NULL;
 
437
        if (PyDict_GetItem(self->dict, key) == NULL) {
 
438
                errno = ENOENT;
 
439
                PyErr_SetFromErrno(PyExc_IOError);
 
440
                return NULL;
 
441
        }
 
442
        value = PyLong_FromLong(events);
 
443
        if (value == NULL) {
 
444
                Py_DECREF(key);
 
445
                return NULL;
 
446
        }
 
447
        err = PyDict_SetItem(self->dict, key, value);
 
448
        Py_DECREF(key);
 
449
        Py_DECREF(value);
 
450
        if (err < 0)
 
451
                return NULL;
 
452
 
 
453
        self->ufd_uptodate = 0;
 
454
 
 
455
        Py_INCREF(Py_None);
 
456
        return Py_None;
 
457
}
 
458
 
 
459
 
 
460
PyDoc_STRVAR(poll_unregister_doc,
 
461
"unregister(fd) -> None\n\n\
 
462
Remove a file descriptor being tracked by the polling object.");
 
463
 
 
464
static PyObject *
 
465
poll_unregister(pollObject *self, PyObject *o) 
 
466
{
 
467
        PyObject *key;
 
468
        int fd;
 
469
 
 
470
        fd = PyObject_AsFileDescriptor( o );
 
471
        if (fd == -1) 
 
472
                return NULL;
 
473
 
 
474
        /* Check whether the fd is already in the array */
 
475
        key = PyLong_FromLong(fd);
 
476
        if (key == NULL) 
 
477
                return NULL;
 
478
 
 
479
        if (PyDict_DelItem(self->dict, key) == -1) {
 
480
                Py_DECREF(key);
 
481
                /* This will simply raise the KeyError set by PyDict_DelItem
 
482
                   if the file descriptor isn't registered. */
 
483
                return NULL;
 
484
        }
 
485
 
 
486
        Py_DECREF(key);
 
487
        self->ufd_uptodate = 0;
 
488
 
 
489
        Py_INCREF(Py_None);
 
490
        return Py_None;
 
491
}
 
492
 
 
493
PyDoc_STRVAR(poll_poll_doc,
 
494
"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
 
495
Polls the set of registered file descriptors, returning a list containing \n\
 
496
any descriptors that have events or errors to report.");
 
497
 
 
498
static PyObject *
 
499
poll_poll(pollObject *self, PyObject *args) 
 
500
{
 
501
        PyObject *result_list = NULL, *tout = NULL;
 
502
        int timeout = 0, poll_result, i, j;
 
503
        PyObject *value = NULL, *num = NULL;
 
504
 
 
505
        if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
 
506
                return NULL;
 
507
        }
 
508
 
 
509
        /* Check values for timeout */
 
510
        if (tout == NULL || tout == Py_None)
 
511
                timeout = -1;
 
512
        else if (!PyNumber_Check(tout)) {
 
513
                PyErr_SetString(PyExc_TypeError,
 
514
                                "timeout must be an integer or None");
 
515
                return NULL;
 
516
        }
 
517
        else {
 
518
                tout = PyNumber_Long(tout);
 
519
                if (!tout)
 
520
                        return NULL;
 
521
                timeout = PyLong_AsLong(tout);
 
522
                Py_DECREF(tout);
 
523
                if (timeout == -1 && PyErr_Occurred())
 
524
                        return NULL;
 
525
        }
 
526
 
 
527
        /* Ensure the ufd array is up to date */
 
528
        if (!self->ufd_uptodate) 
 
529
                if (update_ufd_array(self) == 0)
 
530
                        return NULL;
 
531
 
 
532
        /* call poll() */
 
533
        Py_BEGIN_ALLOW_THREADS
 
534
        poll_result = poll(self->ufds, self->ufd_len, timeout);
 
535
        Py_END_ALLOW_THREADS
 
536
 
 
537
        if (poll_result < 0) {
 
538
                PyErr_SetFromErrno(SelectError);
 
539
                return NULL;
 
540
        } 
 
541
       
 
542
        /* build the result list */
 
543
  
 
544
        result_list = PyList_New(poll_result);
 
545
        if (!result_list) 
 
546
                return NULL;
 
547
        else {
 
548
                for (i = 0, j = 0; j < poll_result; j++) {
 
549
                        /* skip to the next fired descriptor */
 
550
                        while (!self->ufds[i].revents) {
 
551
                                i++;
 
552
                        }
 
553
                        /* if we hit a NULL return, set value to NULL
 
554
                           and break out of loop; code at end will
 
555
                           clean up result_list */
 
556
                        value = PyTuple_New(2);
 
557
                        if (value == NULL)
 
558
                                goto error;
 
559
                        num = PyLong_FromLong(self->ufds[i].fd);
 
560
                        if (num == NULL) {
 
561
                                Py_DECREF(value);
 
562
                                goto error;
 
563
                        }
 
564
                        PyTuple_SET_ITEM(value, 0, num);
 
565
 
 
566
                        /* The &0xffff is a workaround for AIX.  'revents'
 
567
                           is a 16-bit short, and IBM assigned POLLNVAL
 
568
                           to be 0x8000, so the conversion to int results
 
569
                           in a negative number. See SF bug #923315. */
 
570
                        num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
 
571
                        if (num == NULL) {
 
572
                                Py_DECREF(value);
 
573
                                goto error;
 
574
                        }
 
575
                        PyTuple_SET_ITEM(value, 1, num);
 
576
                        if ((PyList_SetItem(result_list, j, value)) == -1) {
 
577
                                Py_DECREF(value);
 
578
                                goto error;
 
579
                        }
 
580
                        i++;
 
581
                }
 
582
        }
 
583
        return result_list;
 
584
 
 
585
  error:
 
586
        Py_DECREF(result_list);
 
587
        return NULL;
 
588
}
 
589
 
 
590
static PyMethodDef poll_methods[] = {
 
591
        {"register",    (PyCFunction)poll_register,     
 
592
         METH_VARARGS,  poll_register_doc},
 
593
        {"modify",      (PyCFunction)poll_modify,
 
594
         METH_VARARGS,  poll_modify_doc},
 
595
        {"unregister",  (PyCFunction)poll_unregister,
 
596
         METH_O,        poll_unregister_doc},
 
597
        {"poll",        (PyCFunction)poll_poll, 
 
598
         METH_VARARGS,  poll_poll_doc},
 
599
        {NULL,          NULL}           /* sentinel */
 
600
};
 
601
 
 
602
static pollObject *
 
603
newPollObject(void)
 
604
{
 
605
        pollObject *self;
 
606
        self = PyObject_New(pollObject, &poll_Type);
 
607
        if (self == NULL)
 
608
                return NULL;
 
609
        /* ufd_uptodate is a Boolean, denoting whether the 
 
610
           array pointed to by ufds matches the contents of the dictionary. */
 
611
        self->ufd_uptodate = 0;
 
612
        self->ufds = NULL;
 
613
        self->dict = PyDict_New();
 
614
        if (self->dict == NULL) {
 
615
                Py_DECREF(self);
 
616
                return NULL;
 
617
        }
 
618
        return self;
 
619
}
 
620
 
 
621
static void
 
622
poll_dealloc(pollObject *self)
 
623
{
 
624
        if (self->ufds != NULL)
 
625
                PyMem_DEL(self->ufds);
 
626
        Py_XDECREF(self->dict);
 
627
        PyObject_Del(self);
 
628
}
 
629
 
 
630
static PyTypeObject poll_Type = {
 
631
        /* The ob_type field must be initialized in the module init function
 
632
         * to be portable to Windows without using C++. */
 
633
        PyVarObject_HEAD_INIT(NULL, 0)
 
634
        "select.poll",          /*tp_name*/
 
635
        sizeof(pollObject),     /*tp_basicsize*/
 
636
        0,                      /*tp_itemsize*/
 
637
        /* methods */
 
638
        (destructor)poll_dealloc, /*tp_dealloc*/
 
639
        0,                      /*tp_print*/
 
640
        0,                      /*tp_getattr*/
 
641
        0,                      /*tp_setattr*/
 
642
        0,                      /*tp_reserved*/
 
643
        0,                      /*tp_repr*/
 
644
        0,                      /*tp_as_number*/
 
645
        0,                      /*tp_as_sequence*/
 
646
        0,                      /*tp_as_mapping*/
 
647
        0,                      /*tp_hash*/
 
648
        0,                      /*tp_call*/
 
649
        0,                      /*tp_str*/
 
650
        0,                      /*tp_getattro*/
 
651
        0,                      /*tp_setattro*/
 
652
        0,                      /*tp_as_buffer*/
 
653
        Py_TPFLAGS_DEFAULT,     /*tp_flags*/
 
654
        0,                      /*tp_doc*/
 
655
        0,                      /*tp_traverse*/
 
656
        0,                      /*tp_clear*/
 
657
        0,                      /*tp_richcompare*/
 
658
        0,                      /*tp_weaklistoffset*/
 
659
        0,                      /*tp_iter*/
 
660
        0,                      /*tp_iternext*/
 
661
        poll_methods,           /*tp_methods*/
 
662
};
 
663
 
 
664
PyDoc_STRVAR(poll_doc,
 
665
"Returns a polling object, which supports registering and\n\
 
666
unregistering file descriptors, and then polling them for I/O events.");
 
667
 
 
668
static PyObject *
 
669
select_poll(PyObject *self, PyObject *unused)
 
670
{
 
671
        return (PyObject *)newPollObject();
 
672
}
 
673
 
 
674
#ifdef __APPLE__
 
675
/* 
 
676
 * On some systems poll() sets errno on invalid file descriptors. We test
 
677
 * for this at runtime because this bug may be fixed or introduced between
 
678
 * OS releases.
 
679
 */
 
680
static int select_have_broken_poll(void)
 
681
{
 
682
        int poll_test;
 
683
        int filedes[2];
 
684
 
 
685
        struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
 
686
 
 
687
        /* Create a file descriptor to make invalid */
 
688
        if (pipe(filedes) < 0) {
 
689
                return 1;
 
690
        }
 
691
        poll_struct.fd = filedes[0];
 
692
        close(filedes[0]);
 
693
        close(filedes[1]);
 
694
        poll_test = poll(&poll_struct, 1, 0);
 
695
        if (poll_test < 0) {
 
696
                return 1;
 
697
        } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
 
698
                return 1;
 
699
        }
 
700
        return 0;
 
701
}
 
702
#endif /* __APPLE__ */
 
703
 
 
704
#endif /* HAVE_POLL */
 
705
 
 
706
#ifdef HAVE_EPOLL
 
707
/* **************************************************************************
 
708
 *                      epoll interface for Linux 2.6
 
709
 *
 
710
 * Written by Christian Heimes
 
711
 * Inspired by Twisted's _epoll.pyx and select.poll()
 
712
 */
 
713
 
 
714
#ifdef HAVE_SYS_EPOLL_H
 
715
#include <sys/epoll.h>
 
716
#endif
 
717
 
 
718
typedef struct {
 
719
        PyObject_HEAD
 
720
        SOCKET epfd;                    /* epoll control file descriptor */
 
721
} pyEpoll_Object;
 
722
 
 
723
static PyTypeObject pyEpoll_Type;
 
724
#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
 
725
 
 
726
static PyObject *
 
727
pyepoll_err_closed(void)
 
728
{
 
729
        PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
 
730
        return NULL;
 
731
}
 
732
 
 
733
static int
 
734
pyepoll_internal_close(pyEpoll_Object *self)
 
735
{
 
736
        int save_errno = 0;
 
737
        if (self->epfd >= 0) {
 
738
                int epfd = self->epfd;
 
739
                self->epfd = -1;
 
740
                Py_BEGIN_ALLOW_THREADS
 
741
                if (close(epfd) < 0)
 
742
                        save_errno = errno;
 
743
                Py_END_ALLOW_THREADS
 
744
        }
 
745
        return save_errno;
 
746
}
 
747
 
 
748
static PyObject *
 
749
newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
 
750
{
 
751
        pyEpoll_Object *self;
 
752
        
 
753
        if (sizehint == -1) {
 
754
                sizehint = FD_SETSIZE-1;
 
755
        }
 
756
        else if (sizehint < 1) {
 
757
                PyErr_Format(PyExc_ValueError,
 
758
                             "sizehint must be greater zero, got %d",
 
759
                             sizehint);
 
760
                return NULL;
 
761
        }
 
762
 
 
763
        assert(type != NULL && type->tp_alloc != NULL);
 
764
        self = (pyEpoll_Object *) type->tp_alloc(type, 0);
 
765
        if (self == NULL)
 
766
                return NULL;
 
767
 
 
768
        if (fd == -1) {
 
769
                Py_BEGIN_ALLOW_THREADS
 
770
                self->epfd = epoll_create(sizehint);
 
771
                Py_END_ALLOW_THREADS
 
772
        }
 
773
        else {
 
774
                self->epfd = fd;
 
775
        }
 
776
        if (self->epfd < 0) {
 
777
                Py_DECREF(self);
 
778
                PyErr_SetFromErrno(PyExc_IOError);
 
779
                return NULL;
 
780
        }
 
781
        return (PyObject *)self;
 
782
}
 
783
 
 
784
 
 
785
static PyObject *
 
786
pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
787
{
 
788
        int sizehint = -1;
 
789
        static char *kwlist[] = {"sizehint", NULL};
 
790
 
 
791
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:epoll", kwlist,
 
792
                                         &sizehint))
 
793
                return NULL;
 
794
 
 
795
        return newPyEpoll_Object(type, sizehint, -1);
 
796
}
 
797
 
 
798
 
 
799
static void
 
800
pyepoll_dealloc(pyEpoll_Object *self)
 
801
{
 
802
        (void)pyepoll_internal_close(self);
 
803
        Py_TYPE(self)->tp_free(self);
 
804
}
 
805
 
 
806
static PyObject*
 
807
pyepoll_close(pyEpoll_Object *self)
 
808
{
 
809
        errno = pyepoll_internal_close(self);
 
810
        if (errno < 0) {
 
811
                PyErr_SetFromErrno(PyExc_IOError);
 
812
                return NULL;
 
813
        }
 
814
        Py_RETURN_NONE;
 
815
}
 
816
 
 
817
PyDoc_STRVAR(pyepoll_close_doc,
 
818
"close() -> None\n\
 
819
\n\
 
820
Close the epoll control file descriptor. Further operations on the epoll\n\
 
821
object will raise an exception.");
 
822
 
 
823
static PyObject*
 
824
pyepoll_get_closed(pyEpoll_Object *self)
 
825
{
 
826
        if (self->epfd < 0)
 
827
                Py_RETURN_TRUE;
 
828
        else
 
829
                Py_RETURN_FALSE;
 
830
}
 
831
 
 
832
static PyObject*
 
833
pyepoll_fileno(pyEpoll_Object *self)
 
834
{
 
835
        if (self->epfd < 0)
 
836
                return pyepoll_err_closed();
 
837
        return PyLong_FromLong(self->epfd);
 
838
}
 
839
 
 
840
PyDoc_STRVAR(pyepoll_fileno_doc,
 
841
"fileno() -> int\n\
 
842
\n\
 
843
Return the epoll control file descriptor.");
 
844
 
 
845
static PyObject*
 
846
pyepoll_fromfd(PyObject *cls, PyObject *args)
 
847
{
 
848
        SOCKET fd;
 
849
 
 
850
        if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
 
851
                return NULL;
 
852
 
 
853
        return newPyEpoll_Object((PyTypeObject*)cls, -1, fd);
 
854
}
 
855
 
 
856
PyDoc_STRVAR(pyepoll_fromfd_doc,
 
857
"fromfd(fd) -> epoll\n\
 
858
\n\
 
859
Create an epoll object from a given control fd.");
 
860
 
 
861
static PyObject *
 
862
pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
 
863
{
 
864
        struct epoll_event ev;
 
865
        int result;
 
866
        int fd;
 
867
 
 
868
        if (epfd < 0)
 
869
                return pyepoll_err_closed();
 
870
 
 
871
        fd = PyObject_AsFileDescriptor(pfd);
 
872
        if (fd == -1) {
 
873
                return NULL;
 
874
        }
 
875
 
 
876
        switch(op) {
 
877
            case EPOLL_CTL_ADD:
 
878
            case EPOLL_CTL_MOD:
 
879
                ev.events = events;
 
880
                ev.data.fd = fd;
 
881
                Py_BEGIN_ALLOW_THREADS
 
882
                result = epoll_ctl(epfd, op, fd, &ev);
 
883
                Py_END_ALLOW_THREADS
 
884
                break;
 
885
            case EPOLL_CTL_DEL:
 
886
                /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
 
887
                 * operation required a non-NULL pointer in event, even
 
888
                 * though this argument is ignored. */
 
889
                Py_BEGIN_ALLOW_THREADS
 
890
                result = epoll_ctl(epfd, op, fd, &ev);
 
891
                if (errno == EBADF) {
 
892
                        /* fd already closed */
 
893
                        result = 0;
 
894
                        errno = 0;
 
895
                }
 
896
                Py_END_ALLOW_THREADS
 
897
                break;
 
898
            default:
 
899
                result = -1;
 
900
                errno = EINVAL;
 
901
        }
 
902
 
 
903
        if (result < 0) {
 
904
                PyErr_SetFromErrno(PyExc_IOError);
 
905
                return NULL;
 
906
        }
 
907
        Py_RETURN_NONE;
 
908
}
 
909
 
 
910
static PyObject *
 
911
pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
 
912
{
 
913
        PyObject *pfd;
 
914
        unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
 
915
        static char *kwlist[] = {"fd", "eventmask", NULL};
 
916
 
 
917
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
 
918
                                         &pfd, &events)) {
 
919
                return NULL;
 
920
        }
 
921
 
 
922
        return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
 
923
}
 
924
 
 
925
PyDoc_STRVAR(pyepoll_register_doc,
 
926
"register(fd[, eventmask]) -> bool\n\
 
927
\n\
 
928
Registers a new fd or modifies an already registered fd. register() returns\n\
 
929
True if a new fd was registered or False if the event mask for fd was modified.\n\
 
930
fd is the target file descriptor of the operation.\n\
 
931
events is a bit set composed of the various EPOLL constants; the default\n\
 
932
is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
 
933
\n\
 
934
The epoll interface supports all file descriptors that support poll.");
 
935
 
 
936
static PyObject *
 
937
pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
 
938
{
 
939
        PyObject *pfd;
 
940
        unsigned int events;
 
941
        static char *kwlist[] = {"fd", "eventmask", NULL};
 
942
 
 
943
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
 
944
                                         &pfd, &events)) {
 
945
                return NULL;
 
946
        }
 
947
 
 
948
        return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
 
949
}
 
950
 
 
951
PyDoc_STRVAR(pyepoll_modify_doc,
 
952
"modify(fd, eventmask) -> None\n\
 
953
\n\
 
954
fd is the target file descriptor of the operation\n\
 
955
events is a bit set composed of the various EPOLL constants");
 
956
 
 
957
static PyObject *
 
958
pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
 
959
{
 
960
        PyObject *pfd;
 
961
        static char *kwlist[] = {"fd", NULL};
 
962
 
 
963
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
 
964
                                         &pfd)) {
 
965
                return NULL;
 
966
        }
 
967
 
 
968
        return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
 
969
}
 
970
 
 
971
PyDoc_STRVAR(pyepoll_unregister_doc,
 
972
"unregister(fd) -> None\n\
 
973
\n\
 
974
fd is the target file descriptor of the operation.");
 
975
 
 
976
static PyObject *
 
977
pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
 
978
{
 
979
        double dtimeout = -1.;
 
980
        int timeout;
 
981
        int maxevents = -1;
 
982
        int nfds, i;
 
983
        PyObject *elist = NULL, *etuple = NULL;
 
984
        struct epoll_event *evs = NULL;
 
985
        static char *kwlist[] = {"timeout", "maxevents", NULL};
 
986
 
 
987
        if (self->epfd < 0)
 
988
                return pyepoll_err_closed();
 
989
 
 
990
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
 
991
                                         &dtimeout, &maxevents)) {
 
992
                return NULL;
 
993
        }
 
994
 
 
995
        if (dtimeout < 0) {
 
996
                timeout = -1;
 
997
        }
 
998
        else if (dtimeout * 1000.0 > INT_MAX) {
 
999
                PyErr_SetString(PyExc_OverflowError,
 
1000
                                "timeout is too large");
 
1001
                return NULL;
 
1002
        }
 
1003
        else {
 
1004
                timeout = (int)(dtimeout * 1000.0);
 
1005
        }
 
1006
 
 
1007
        if (maxevents == -1) {
 
1008
                maxevents = FD_SETSIZE-1;
 
1009
        }
 
1010
        else if (maxevents < 1) {
 
1011
                PyErr_Format(PyExc_ValueError,
 
1012
                             "maxevents must be greater than 0, got %d",
 
1013
                             maxevents);
 
1014
                return NULL;
 
1015
        }
 
1016
 
 
1017
        evs = PyMem_New(struct epoll_event, maxevents);
 
1018
        if (evs == NULL) {
 
1019
                Py_DECREF(self);
 
1020
                PyErr_NoMemory();
 
1021
                return NULL;
 
1022
        }
 
1023
 
 
1024
        Py_BEGIN_ALLOW_THREADS
 
1025
        nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
 
1026
        Py_END_ALLOW_THREADS
 
1027
        if (nfds < 0) {
 
1028
                PyErr_SetFromErrno(PyExc_IOError);
 
1029
                goto error;
 
1030
        }
 
1031
 
 
1032
        elist = PyList_New(nfds);
 
1033
        if (elist == NULL) {
 
1034
                goto error;
 
1035
        }
 
1036
 
 
1037
        for (i = 0; i < nfds; i++) {
 
1038
                etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
 
1039
                if (etuple == NULL) {
 
1040
                        Py_CLEAR(elist);
 
1041
                        goto error;
 
1042
                }
 
1043
                PyList_SET_ITEM(elist, i, etuple);
 
1044
        }
 
1045
 
 
1046
    error:
 
1047
        PyMem_Free(evs);
 
1048
        return elist;
 
1049
}
 
1050
 
 
1051
PyDoc_STRVAR(pyepoll_poll_doc,
 
1052
"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
 
1053
\n\
 
1054
Wait for events on the epoll file descriptor for a maximum time of timeout\n\
 
1055
in seconds (as float). -1 makes poll wait indefinitely.\n\
 
1056
Up to maxevents are returned to the caller.");
 
1057
 
 
1058
static PyMethodDef pyepoll_methods[] = {
 
1059
        {"fromfd",      (PyCFunction)pyepoll_fromfd,
 
1060
         METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
 
1061
        {"close",       (PyCFunction)pyepoll_close,     METH_NOARGS,
 
1062
         pyepoll_close_doc},
 
1063
        {"fileno",      (PyCFunction)pyepoll_fileno,    METH_NOARGS,
 
1064
         pyepoll_fileno_doc},
 
1065
        {"modify",      (PyCFunction)pyepoll_modify,
 
1066
         METH_VARARGS | METH_KEYWORDS,  pyepoll_modify_doc},
 
1067
        {"register",    (PyCFunction)pyepoll_register,
 
1068
         METH_VARARGS | METH_KEYWORDS,  pyepoll_register_doc},
 
1069
        {"unregister",  (PyCFunction)pyepoll_unregister,
 
1070
         METH_VARARGS | METH_KEYWORDS,  pyepoll_unregister_doc},
 
1071
        {"poll",        (PyCFunction)pyepoll_poll,
 
1072
         METH_VARARGS | METH_KEYWORDS,  pyepoll_poll_doc},
 
1073
        {NULL,  NULL},
 
1074
};
 
1075
 
 
1076
static PyGetSetDef pyepoll_getsetlist[] = {
 
1077
        {"closed", (getter)pyepoll_get_closed, NULL,
 
1078
         "True if the epoll handler is closed"},
 
1079
        {0},
 
1080
};
 
1081
 
 
1082
PyDoc_STRVAR(pyepoll_doc,
 
1083
"select.epoll([sizehint=-1])\n\
 
1084
\n\
 
1085
Returns an epolling object\n\
 
1086
\n\
 
1087
sizehint must be a positive integer or -1 for the default size. The\n\
 
1088
sizehint is used to optimize internal data structures. It doesn't limit\n\
 
1089
the maximum number of monitored events.");
 
1090
 
 
1091
static PyTypeObject pyEpoll_Type = {
 
1092
        PyVarObject_HEAD_INIT(NULL, 0)
 
1093
        "select.epoll",                                 /* tp_name */
 
1094
        sizeof(pyEpoll_Object),                         /* tp_basicsize */
 
1095
        0,                                              /* tp_itemsize */
 
1096
        (destructor)pyepoll_dealloc,                    /* tp_dealloc */
 
1097
        0,                                              /* tp_print */
 
1098
        0,                                              /* tp_getattr */
 
1099
        0,                                              /* tp_setattr */
 
1100
        0,                                              /* tp_reserved */
 
1101
        0,                                              /* tp_repr */
 
1102
        0,                                              /* tp_as_number */
 
1103
        0,                                              /* tp_as_sequence */
 
1104
        0,                                              /* tp_as_mapping */
 
1105
        0,                                              /* tp_hash */
 
1106
        0,                                              /* tp_call */
 
1107
        0,                                              /* tp_str */
 
1108
        PyObject_GenericGetAttr,                        /* tp_getattro */
 
1109
        0,                                              /* tp_setattro */
 
1110
        0,                                              /* tp_as_buffer */
 
1111
        Py_TPFLAGS_DEFAULT,                             /* tp_flags */
 
1112
        pyepoll_doc,                                    /* tp_doc */
 
1113
        0,                                              /* tp_traverse */
 
1114
        0,                                              /* tp_clear */
 
1115
        0,                                              /* tp_richcompare */
 
1116
        0,                                              /* tp_weaklistoffset */
 
1117
        0,                                              /* tp_iter */
 
1118
        0,                                              /* tp_iternext */
 
1119
        pyepoll_methods,                                /* tp_methods */
 
1120
        0,                                              /* tp_members */
 
1121
        pyepoll_getsetlist,                             /* tp_getset */
 
1122
        0,                                              /* tp_base */
 
1123
        0,                                              /* tp_dict */
 
1124
        0,                                              /* tp_descr_get */
 
1125
        0,                                              /* tp_descr_set */
 
1126
        0,                                              /* tp_dictoffset */
 
1127
        0,                                              /* tp_init */
 
1128
        0,                                              /* tp_alloc */
 
1129
        pyepoll_new,                                    /* tp_new */
 
1130
        0,                                              /* tp_free */
 
1131
};
 
1132
 
 
1133
#endif /* HAVE_EPOLL */
 
1134
 
 
1135
#ifdef HAVE_KQUEUE
 
1136
/* **************************************************************************
 
1137
 *                      kqueue interface for BSD
 
1138
 *
 
1139
 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
 
1140
 * All rights reserved.
 
1141
 *
 
1142
 * Redistribution and use in source and binary forms, with or without
 
1143
 * modification, are permitted provided that the following conditions
 
1144
 * are met:
 
1145
 * 1. Redistributions of source code must retain the above copyright
 
1146
 *    notice, this list of conditions and the following disclaimer.
 
1147
 * 2. Redistributions in binary form must reproduce the above copyright
 
1148
 *    notice, this list of conditions and the following disclaimer in the
 
1149
 *    documentation and/or other materials provided with the distribution.
 
1150
 *
 
1151
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 
1152
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
1153
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
1154
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 
1155
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
1156
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 
1157
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
1158
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
1159
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 
1160
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
1161
 * SUCH DAMAGE.
 
1162
 */
 
1163
 
 
1164
#ifdef HAVE_SYS_EVENT_H
 
1165
#include <sys/event.h>
 
1166
#endif
 
1167
 
 
1168
PyDoc_STRVAR(kqueue_event_doc,
 
1169
"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_ADD, fflags=0, data=0, udata=0)\n\
 
1170
\n\
 
1171
This object is the equivalent of the struct kevent for the C API.\n\
 
1172
\n\
 
1173
See the kqueue manpage for more detailed information about the meaning\n\
 
1174
of the arguments.\n\
 
1175
\n\
 
1176
One minor note: while you might hope that udata could store a\n\
 
1177
reference to a python object, it cannot, because it is impossible to\n\
 
1178
keep a proper reference count of the object once it's passed into the\n\
 
1179
kernel. Therefore, I have restricted it to only storing an integer.  I\n\
 
1180
recommend ignoring it and simply using the 'ident' field to key off\n\
 
1181
of. You could also set up a dictionary on the python side to store a\n\
 
1182
udata->object mapping.");
 
1183
 
 
1184
typedef struct {
 
1185
        PyObject_HEAD
 
1186
        struct kevent e;
 
1187
} kqueue_event_Object;
 
1188
 
 
1189
static PyTypeObject kqueue_event_Type;
 
1190
 
 
1191
#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
 
1192
 
 
1193
typedef struct {
 
1194
        PyObject_HEAD
 
1195
        SOCKET kqfd;            /* kqueue control fd */
 
1196
} kqueue_queue_Object;
 
1197
 
 
1198
static PyTypeObject kqueue_queue_Type;
 
1199
 
 
1200
#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
 
1201
 
 
1202
/* Unfortunately, we can't store python objects in udata, because
 
1203
 * kevents in the kernel can be removed without warning, which would
 
1204
 * forever lose the refcount on the object stored with it.
 
1205
 */
 
1206
 
 
1207
#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
 
1208
static struct PyMemberDef kqueue_event_members[] = {
 
1209
        {"ident",       T_UINT,         KQ_OFF(e.ident)},
 
1210
        {"filter",      T_SHORT,        KQ_OFF(e.filter)},
 
1211
        {"flags",       T_USHORT,       KQ_OFF(e.flags)},
 
1212
        {"fflags",      T_UINT,         KQ_OFF(e.fflags)},
 
1213
        {"data",        T_INT,          KQ_OFF(e.data)},
 
1214
        {"udata",       T_INT,          KQ_OFF(e.udata)},
 
1215
        {NULL} /* Sentinel */
 
1216
};
 
1217
#undef KQ_OFF
 
1218
 
 
1219
static PyObject *
 
1220
kqueue_event_repr(kqueue_event_Object *s)
 
1221
{
 
1222
        char buf[1024];
 
1223
        PyOS_snprintf(
 
1224
                buf, sizeof(buf),
 
1225
                "<select.kevent ident=%lu filter=%d flags=0x%x fflags=0x%x "
 
1226
                "data=0x%lx udata=%p>",
 
1227
                (unsigned long)(s->e.ident), s->e.filter, s->e.flags,
 
1228
                s->e.fflags, (long)(s->e.data), s->e.udata);
 
1229
        return PyBytes_FromString(buf);
 
1230
}
 
1231
 
 
1232
static int
 
1233
kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
 
1234
{
 
1235
        PyObject *pfd;
 
1236
        static char *kwlist[] = {"ident", "filter", "flags", "fflags",
 
1237
                                 "data", "udata", NULL};
 
1238
 
 
1239
        EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
 
1240
        
 
1241
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|hhiii:kevent", kwlist,
 
1242
                &pfd, &(self->e.filter), &(self->e.flags),
 
1243
                &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
 
1244
                return -1;
 
1245
        }
 
1246
 
 
1247
        self->e.ident = PyObject_AsFileDescriptor(pfd);
 
1248
        if (self->e.ident == -1) {
 
1249
                return -1;
 
1250
        }
 
1251
        return 0;
 
1252
}
 
1253
 
 
1254
static PyObject *
 
1255
kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
 
1256
                         int op)
 
1257
{
 
1258
        int result = 0;
 
1259
 
 
1260
        if (!kqueue_event_Check(o)) {
 
1261
                if (op == Py_EQ || op == Py_NE) {
 
1262
                        PyObject *res = op == Py_EQ ? Py_False : Py_True;
 
1263
                        Py_INCREF(res);
 
1264
                        return res;
 
1265
                }
 
1266
                PyErr_Format(PyExc_TypeError,
 
1267
                        "can't compare %.200s to %.200s",
 
1268
                        Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
 
1269
                return NULL;
 
1270
        }
 
1271
        if (((result = s->e.ident - o->e.ident) == 0) &&
 
1272
            ((result = s->e.filter - o->e.filter) == 0) &&
 
1273
            ((result = s->e.flags - o->e.flags) == 0) &&
 
1274
            ((result = s->e.fflags - o->e.fflags) == 0) &&
 
1275
            ((result = s->e.data - o->e.data) == 0) &&
 
1276
            ((result = s->e.udata - o->e.udata) == 0)
 
1277
           ) {
 
1278
                result = 0;
 
1279
        }
 
1280
 
 
1281
        switch (op) {
 
1282
            case Py_EQ:
 
1283
                result = (result == 0);
 
1284
                break;
 
1285
            case Py_NE:
 
1286
                result = (result != 0);
 
1287
                break;
 
1288
            case Py_LE:
 
1289
                result = (result <= 0);
 
1290
                break;
 
1291
            case Py_GE:
 
1292
                result = (result >= 0);
 
1293
                break;
 
1294
            case Py_LT:
 
1295
                result = (result < 0);
 
1296
                break;
 
1297
            case Py_GT:
 
1298
                result = (result > 0);
 
1299
                break;
 
1300
        }
 
1301
        return PyBool_FromLong(result);
 
1302
}
 
1303
 
 
1304
static PyTypeObject kqueue_event_Type = {
 
1305
        PyVarObject_HEAD_INIT(NULL, 0)
 
1306
        "select.kevent",                                /* tp_name */
 
1307
        sizeof(kqueue_event_Object),                    /* tp_basicsize */
 
1308
        0,                                              /* tp_itemsize */
 
1309
        0,                                              /* tp_dealloc */
 
1310
        0,                                              /* tp_print */
 
1311
        0,                                              /* tp_getattr */
 
1312
        0,                                              /* tp_setattr */
 
1313
        0,                                              /* tp_reserved */
 
1314
        (reprfunc)kqueue_event_repr,                    /* tp_repr */
 
1315
        0,                                              /* tp_as_number */
 
1316
        0,                                              /* tp_as_sequence */
 
1317
        0,                                              /* tp_as_mapping */
 
1318
        0,                                              /* tp_hash */
 
1319
        0,                                              /* tp_call */
 
1320
        0,                                              /* tp_str */
 
1321
        0,                                              /* tp_getattro */
 
1322
        0,                                              /* tp_setattro */
 
1323
        0,                                              /* tp_as_buffer */
 
1324
        Py_TPFLAGS_DEFAULT,                             /* tp_flags */
 
1325
        kqueue_event_doc,                               /* tp_doc */
 
1326
        0,                                              /* tp_traverse */
 
1327
        0,                                              /* tp_clear */
 
1328
        (richcmpfunc)kqueue_event_richcompare,          /* tp_richcompare */
 
1329
        0,                                              /* tp_weaklistoffset */
 
1330
        0,                                              /* tp_iter */
 
1331
        0,                                              /* tp_iternext */
 
1332
        0,                                              /* tp_methods */
 
1333
        kqueue_event_members,                           /* tp_members */
 
1334
        0,                                              /* tp_getset */
 
1335
        0,                                              /* tp_base */
 
1336
        0,                                              /* tp_dict */
 
1337
        0,                                              /* tp_descr_get */
 
1338
        0,                                              /* tp_descr_set */
 
1339
        0,                                              /* tp_dictoffset */
 
1340
        (initproc)kqueue_event_init,                    /* tp_init */
 
1341
        0,                                              /* tp_alloc */
 
1342
        0,                                              /* tp_new */
 
1343
        0,                                              /* tp_free */
 
1344
};
 
1345
 
 
1346
static PyObject *
 
1347
kqueue_queue_err_closed(void)
 
1348
{
 
1349
        PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
 
1350
        return NULL;
 
1351
}
 
1352
 
 
1353
static int
 
1354
kqueue_queue_internal_close(kqueue_queue_Object *self)
 
1355
{
 
1356
        int save_errno = 0;
 
1357
        if (self->kqfd >= 0) {
 
1358
                int kqfd = self->kqfd;
 
1359
                self->kqfd = -1;
 
1360
                Py_BEGIN_ALLOW_THREADS
 
1361
                if (close(kqfd) < 0)
 
1362
                        save_errno = errno;
 
1363
                Py_END_ALLOW_THREADS
 
1364
        }
 
1365
        return save_errno;
 
1366
}
 
1367
 
 
1368
static PyObject *
 
1369
newKqueue_Object(PyTypeObject *type, SOCKET fd)
 
1370
{
 
1371
        kqueue_queue_Object *self;
 
1372
        assert(type != NULL && type->tp_alloc != NULL);
 
1373
        self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
 
1374
        if (self == NULL) {
 
1375
                return NULL;
 
1376
        }
 
1377
        
 
1378
        if (fd == -1) {
 
1379
                Py_BEGIN_ALLOW_THREADS
 
1380
                self->kqfd = kqueue();
 
1381
                Py_END_ALLOW_THREADS
 
1382
        }
 
1383
        else {
 
1384
                self->kqfd = fd;
 
1385
        }
 
1386
        if (self->kqfd < 0) {
 
1387
                Py_DECREF(self);
 
1388
                PyErr_SetFromErrno(PyExc_IOError);
 
1389
                return NULL;
 
1390
        }
 
1391
        return (PyObject *)self;
 
1392
}
 
1393
 
 
1394
static PyObject *
 
1395
kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
1396
{
 
1397
 
 
1398
        if ((args != NULL && PyObject_Size(args)) ||
 
1399
                        (kwds != NULL && PyObject_Size(kwds))) {
 
1400
                PyErr_SetString(PyExc_ValueError,
 
1401
                                "select.kqueue doesn't accept arguments");
 
1402
                return NULL;
 
1403
        }
 
1404
 
 
1405
        return newKqueue_Object(type, -1);
 
1406
}
 
1407
 
 
1408
static void
 
1409
kqueue_queue_dealloc(kqueue_queue_Object *self)
 
1410
{
 
1411
        kqueue_queue_internal_close(self);
 
1412
        Py_TYPE(self)->tp_free(self);
 
1413
}
 
1414
 
 
1415
static PyObject*
 
1416
kqueue_queue_close(kqueue_queue_Object *self)
 
1417
{
 
1418
        errno = kqueue_queue_internal_close(self);
 
1419
        if (errno < 0) {
 
1420
                PyErr_SetFromErrno(PyExc_IOError);
 
1421
                return NULL;
 
1422
        }
 
1423
        Py_RETURN_NONE;
 
1424
}
 
1425
 
 
1426
PyDoc_STRVAR(kqueue_queue_close_doc,
 
1427
"close() -> None\n\
 
1428
\n\
 
1429
Close the kqueue control file descriptor. Further operations on the kqueue\n\
 
1430
object will raise an exception.");
 
1431
 
 
1432
static PyObject*
 
1433
kqueue_queue_get_closed(kqueue_queue_Object *self)
 
1434
{
 
1435
        if (self->kqfd < 0)
 
1436
                Py_RETURN_TRUE;
 
1437
        else
 
1438
                Py_RETURN_FALSE;
 
1439
}
 
1440
 
 
1441
static PyObject*
 
1442
kqueue_queue_fileno(kqueue_queue_Object *self)
 
1443
{
 
1444
        if (self->kqfd < 0)
 
1445
                return kqueue_queue_err_closed();
 
1446
        return PyLong_FromLong(self->kqfd);
 
1447
}
 
1448
 
 
1449
PyDoc_STRVAR(kqueue_queue_fileno_doc,
 
1450
"fileno() -> int\n\
 
1451
\n\
 
1452
Return the kqueue control file descriptor.");
 
1453
 
 
1454
static PyObject*
 
1455
kqueue_queue_fromfd(PyObject *cls, PyObject *args)
 
1456
{
 
1457
        SOCKET fd;
 
1458
 
 
1459
        if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
 
1460
                return NULL;
 
1461
 
 
1462
        return newKqueue_Object((PyTypeObject*)cls, fd);
 
1463
}
 
1464
 
 
1465
PyDoc_STRVAR(kqueue_queue_fromfd_doc,
 
1466
"fromfd(fd) -> kqueue\n\
 
1467
\n\
 
1468
Create a kqueue object from a given control fd.");
 
1469
 
 
1470
static PyObject *
 
1471
kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
 
1472
{
 
1473
        int nevents = 0;
 
1474
        int gotevents = 0;
 
1475
        int nchanges = 0;
 
1476
        int i = 0;
 
1477
        PyObject *otimeout = NULL;
 
1478
        PyObject *ch = NULL;
 
1479
        PyObject *it = NULL, *ei = NULL;
 
1480
        PyObject *result = NULL;
 
1481
        struct kevent *evl = NULL;
 
1482
        struct kevent *chl = NULL;
 
1483
        struct timespec timeoutspec;
 
1484
        struct timespec *ptimeoutspec;
 
1485
 
 
1486
        if (self->kqfd < 0)
 
1487
                return kqueue_queue_err_closed();
 
1488
 
 
1489
        if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
 
1490
                return NULL;
 
1491
 
 
1492
        if (nevents < 0) {
 
1493
                PyErr_Format(PyExc_ValueError,
 
1494
                        "Length of eventlist must be 0 or positive, got %d",
 
1495
                        nchanges);
 
1496
                return NULL;
 
1497
        }
 
1498
 
 
1499
        if (ch != NULL && ch != Py_None) {
 
1500
                it = PyObject_GetIter(ch);
 
1501
                if (it == NULL) {
 
1502
                        PyErr_SetString(PyExc_TypeError,
 
1503
                                        "changelist is not iterable");
 
1504
                        return NULL;
 
1505
                }
 
1506
                nchanges = PyObject_Size(ch);
 
1507
                if (nchanges < 0) {
 
1508
                        return NULL;
 
1509
                }
 
1510
        }
 
1511
 
 
1512
        if (otimeout == Py_None || otimeout == NULL) {
 
1513
                ptimeoutspec = NULL;
 
1514
        }
 
1515
        else if (PyNumber_Check(otimeout)) {
 
1516
                double timeout;
 
1517
                long seconds;
 
1518
 
 
1519
                timeout = PyFloat_AsDouble(otimeout);
 
1520
                if (timeout == -1 && PyErr_Occurred())
 
1521
                        return NULL;
 
1522
                if (timeout > (double)LONG_MAX) {
 
1523
                        PyErr_SetString(PyExc_OverflowError,
 
1524
                                        "timeout period too long");
 
1525
                        return NULL;
 
1526
                }
 
1527
                if (timeout < 0) {
 
1528
                        PyErr_SetString(PyExc_ValueError,
 
1529
                                        "timeout must be positive or None");
 
1530
                        return NULL;
 
1531
                }
 
1532
 
 
1533
                seconds = (long)timeout;
 
1534
                timeout = timeout - (double)seconds;
 
1535
                timeoutspec.tv_sec = seconds;
 
1536
                timeoutspec.tv_nsec = (long)(timeout * 1E9);
 
1537
                ptimeoutspec = &timeoutspec;
 
1538
        }
 
1539
        else {
 
1540
                PyErr_Format(PyExc_TypeError,
 
1541
                        "timeout argument must be an number "
 
1542
                        "or None, got %.200s",
 
1543
                        Py_TYPE(otimeout)->tp_name);
 
1544
                return NULL;
 
1545
        }
 
1546
 
 
1547
        if (nchanges) {
 
1548
                chl = PyMem_New(struct kevent, nchanges);
 
1549
                if (chl == NULL) {
 
1550
                        PyErr_NoMemory();
 
1551
                        return NULL;
 
1552
                }
 
1553
                while ((ei = PyIter_Next(it)) != NULL) {
 
1554
                        if (!kqueue_event_Check(ei)) {
 
1555
                                Py_DECREF(ei);
 
1556
                                PyErr_SetString(PyExc_TypeError,
 
1557
                                        "changelist must be an iterable of "
 
1558
                                        "select.kevent objects");
 
1559
                                goto error;
 
1560
                        } else {
 
1561
                                chl[i] = ((kqueue_event_Object *)ei)->e;
 
1562
                        }
 
1563
                        Py_DECREF(ei);
 
1564
                }
 
1565
        }
 
1566
        Py_CLEAR(it);
 
1567
 
 
1568
        /* event list */
 
1569
        if (nevents) {
 
1570
                evl = PyMem_New(struct kevent, nevents);
 
1571
                if (evl == NULL) {
 
1572
                        PyErr_NoMemory();
 
1573
                        return NULL;
 
1574
                }
 
1575
        }
 
1576
 
 
1577
        Py_BEGIN_ALLOW_THREADS
 
1578
        gotevents = kevent(self->kqfd, chl, nchanges,
 
1579
                           evl, nevents, ptimeoutspec);
 
1580
        Py_END_ALLOW_THREADS
 
1581
 
 
1582
        if (gotevents == -1) {
 
1583
                PyErr_SetFromErrno(PyExc_OSError);
 
1584
                goto error;
 
1585
        }
 
1586
 
 
1587
        result = PyList_New(gotevents);
 
1588
        if (result == NULL) {
 
1589
                goto error;
 
1590
        }
 
1591
 
 
1592
        for (i=0; i < gotevents; i++) {
 
1593
                kqueue_event_Object *ch;
 
1594
 
 
1595
                ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
 
1596
                if (ch == NULL) {
 
1597
                        goto error;
 
1598
                }
 
1599
                ch->e = evl[i];
 
1600
                PyList_SET_ITEM(result, i, (PyObject *)ch);
 
1601
        }
 
1602
        PyMem_Free(chl);
 
1603
        PyMem_Free(evl);
 
1604
        return result;
 
1605
 
 
1606
    error:
 
1607
        PyMem_Free(chl);
 
1608
        PyMem_Free(evl);
 
1609
        Py_XDECREF(result);
 
1610
        Py_XDECREF(it);
 
1611
        return NULL;
 
1612
}
 
1613
 
 
1614
PyDoc_STRVAR(kqueue_queue_control_doc,
 
1615
"control(changelist, max_events[, timeout=None]) -> eventlist\n\
 
1616
\n\
 
1617
Calls the kernel kevent function.\n\
 
1618
- changelist must be a list of kevent objects describing the changes\n\
 
1619
  to be made to the kernel's watch list or None.\n\
 
1620
- max_events lets you specify the maximum number of events that the\n\
 
1621
  kernel will return.\n\
 
1622
- timeout is the maximum time to wait in seconds, or else None,\n\
 
1623
  to wait forever. timeout accepts floats for smaller timeouts, too.");
 
1624
 
 
1625
 
 
1626
static PyMethodDef kqueue_queue_methods[] = {
 
1627
        {"fromfd",      (PyCFunction)kqueue_queue_fromfd,
 
1628
         METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
 
1629
        {"close",       (PyCFunction)kqueue_queue_close,        METH_NOARGS,
 
1630
         kqueue_queue_close_doc},
 
1631
        {"fileno",      (PyCFunction)kqueue_queue_fileno,       METH_NOARGS,
 
1632
         kqueue_queue_fileno_doc},
 
1633
        {"control",     (PyCFunction)kqueue_queue_control,
 
1634
         METH_VARARGS , kqueue_queue_control_doc},
 
1635
        {NULL,  NULL},
 
1636
};
 
1637
 
 
1638
static PyGetSetDef kqueue_queue_getsetlist[] = {
 
1639
        {"closed", (getter)kqueue_queue_get_closed, NULL,
 
1640
         "True if the kqueue handler is closed"},
 
1641
        {0},
 
1642
};
 
1643
 
 
1644
PyDoc_STRVAR(kqueue_queue_doc,
 
1645
"Kqueue syscall wrapper.\n\
 
1646
\n\
 
1647
For example, to start watching a socket for input:\n\
 
1648
>>> kq = kqueue()\n\
 
1649
>>> sock = socket()\n\
 
1650
>>> sock.connect((host, port))\n\
 
1651
>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
 
1652
\n\
 
1653
To wait one second for it to become writeable:\n\
 
1654
>>> kq.control(None, 1, 1000)\n\
 
1655
\n\
 
1656
To stop listening:\n\
 
1657
>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
 
1658
 
 
1659
static PyTypeObject kqueue_queue_Type = {
 
1660
        PyVarObject_HEAD_INIT(NULL, 0)
 
1661
        "select.kqueue",                                /* tp_name */
 
1662
        sizeof(kqueue_queue_Object),                    /* tp_basicsize */
 
1663
        0,                                              /* tp_itemsize */
 
1664
        (destructor)kqueue_queue_dealloc,               /* tp_dealloc */
 
1665
        0,                                              /* tp_print */
 
1666
        0,                                              /* tp_getattr */
 
1667
        0,                                              /* tp_setattr */
 
1668
        0,                                              /* tp_reserved */
 
1669
        0,                                              /* tp_repr */
 
1670
        0,                                              /* tp_as_number */
 
1671
        0,                                              /* tp_as_sequence */
 
1672
        0,                                              /* tp_as_mapping */
 
1673
        0,                                              /* tp_hash */
 
1674
        0,                                              /* tp_call */
 
1675
        0,                                              /* tp_str */
 
1676
        0,                                              /* tp_getattro */
 
1677
        0,                                              /* tp_setattro */
 
1678
        0,                                              /* tp_as_buffer */
 
1679
        Py_TPFLAGS_DEFAULT,                             /* tp_flags */
 
1680
        kqueue_queue_doc,                               /* tp_doc */
 
1681
        0,                                              /* tp_traverse */
 
1682
        0,                                              /* tp_clear */
 
1683
        0,                                              /* tp_richcompare */
 
1684
        0,                                              /* tp_weaklistoffset */
 
1685
        0,                                              /* tp_iter */
 
1686
        0,                                              /* tp_iternext */
 
1687
        kqueue_queue_methods,                           /* tp_methods */
 
1688
        0,                                              /* tp_members */
 
1689
        kqueue_queue_getsetlist,                        /* tp_getset */
 
1690
        0,                                              /* tp_base */
 
1691
        0,                                              /* tp_dict */
 
1692
        0,                                              /* tp_descr_get */
 
1693
        0,                                              /* tp_descr_set */
 
1694
        0,                                              /* tp_dictoffset */
 
1695
        0,                                              /* tp_init */
 
1696
        0,                                              /* tp_alloc */
 
1697
        kqueue_queue_new,                               /* tp_new */
 
1698
        0,                                              /* tp_free */
 
1699
};
 
1700
 
 
1701
#endif /* HAVE_KQUEUE */
 
1702
/* ************************************************************************ */
 
1703
 
 
1704
PyDoc_STRVAR(select_doc,
 
1705
"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
 
1706
\n\
 
1707
Wait until one or more file descriptors are ready for some kind of I/O.\n\
 
1708
The first three arguments are sequences of file descriptors to be waited for:\n\
 
1709
rlist -- wait until ready for reading\n\
 
1710
wlist -- wait until ready for writing\n\
 
1711
xlist -- wait for an ``exceptional condition''\n\
 
1712
If only one kind of condition is required, pass [] for the other lists.\n\
 
1713
A file descriptor is either a socket or file object, or a small integer\n\
 
1714
gotten from a fileno() method call on one of those.\n\
 
1715
\n\
 
1716
The optional 4th argument specifies a timeout in seconds; it may be\n\
 
1717
a floating point number to specify fractions of seconds.  If it is absent\n\
 
1718
or None, the call will never time out.\n\
 
1719
\n\
 
1720
The return value is a tuple of three lists corresponding to the first three\n\
 
1721
arguments; each contains the subset of the corresponding file descriptors\n\
 
1722
that are ready.\n\
 
1723
\n\
 
1724
*** IMPORTANT NOTICE ***\n\
 
1725
On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
 
1726
descriptors can be used.");
 
1727
 
 
1728
static PyMethodDef select_methods[] = {
 
1729
        {"select",      select_select,  METH_VARARGS,   select_doc},
 
1730
#ifdef HAVE_POLL
 
1731
        {"poll",        select_poll,    METH_NOARGS,    poll_doc},
 
1732
#endif /* HAVE_POLL */
 
1733
        {0,     0},     /* sentinel */
 
1734
};
 
1735
 
 
1736
PyDoc_STRVAR(module_doc,
 
1737
"This module supports asynchronous I/O on multiple file descriptors.\n\
 
1738
\n\
 
1739
*** IMPORTANT NOTICE ***\n\
 
1740
On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
 
1741
 
 
1742
 
 
1743
static struct PyModuleDef selectmodule = {
 
1744
        PyModuleDef_HEAD_INIT,
 
1745
        "select",
 
1746
        module_doc,
 
1747
        -1,
 
1748
        select_methods,
 
1749
        NULL,
 
1750
        NULL,
 
1751
        NULL,
 
1752
        NULL
 
1753
};
 
1754
 
 
1755
PyMODINIT_FUNC
 
1756
PyInit_select(void)
 
1757
{
 
1758
        PyObject *m;
 
1759
        m = PyModule_Create(&selectmodule);
 
1760
        if (m == NULL)
 
1761
                return NULL;
 
1762
 
 
1763
        SelectError = PyErr_NewException("select.error", NULL, NULL);
 
1764
        Py_INCREF(SelectError);
 
1765
        PyModule_AddObject(m, "error", SelectError);
 
1766
 
 
1767
#if defined(HAVE_POLL)
 
1768
#ifdef __APPLE__
 
1769
        if (select_have_broken_poll()) {
 
1770
                if (PyObject_DelAttrString(m, "poll") == -1) {
 
1771
                        PyErr_Clear();
 
1772
                }
 
1773
        } else {
 
1774
#else
 
1775
        {
 
1776
#endif
 
1777
                if (PyType_Ready(&poll_Type) < 0)
 
1778
                        return NULL;
 
1779
                PyModule_AddIntConstant(m, "POLLIN", POLLIN);
 
1780
                PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
 
1781
                PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
 
1782
                PyModule_AddIntConstant(m, "POLLERR", POLLERR);
 
1783
                PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
 
1784
                PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
 
1785
 
 
1786
#ifdef POLLRDNORM
 
1787
                PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
 
1788
#endif
 
1789
#ifdef POLLRDBAND
 
1790
                PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
 
1791
#endif
 
1792
#ifdef POLLWRNORM
 
1793
                PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
 
1794
#endif
 
1795
#ifdef POLLWRBAND
 
1796
                PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
 
1797
#endif
 
1798
#ifdef POLLMSG
 
1799
                PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
 
1800
#endif
 
1801
        }
 
1802
#endif /* HAVE_POLL */
 
1803
 
 
1804
#ifdef HAVE_EPOLL
 
1805
        Py_TYPE(&pyEpoll_Type) = &PyType_Type;
 
1806
        if (PyType_Ready(&pyEpoll_Type) < 0)
 
1807
                return NULL;
 
1808
 
 
1809
        Py_INCREF(&pyEpoll_Type);
 
1810
        PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
 
1811
 
 
1812
        PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
 
1813
        PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
 
1814
        PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
 
1815
        PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
 
1816
        PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
 
1817
        PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
 
1818
#ifdef EPOLLONESHOT
 
1819
        /* Kernel 2.6.2+ */
 
1820
        PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
 
1821
#endif
 
1822
        /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
 
1823
        PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
 
1824
        PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
 
1825
        PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
 
1826
        PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
 
1827
        PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
 
1828
#endif /* HAVE_EPOLL */
 
1829
 
 
1830
#ifdef HAVE_KQUEUE
 
1831
        kqueue_event_Type.tp_new = PyType_GenericNew;
 
1832
        Py_TYPE(&kqueue_event_Type) = &PyType_Type;
 
1833
        if(PyType_Ready(&kqueue_event_Type) < 0)
 
1834
                return NULL;
 
1835
 
 
1836
        Py_INCREF(&kqueue_event_Type);
 
1837
        PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
 
1838
 
 
1839
        Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
 
1840
        if(PyType_Ready(&kqueue_queue_Type) < 0)
 
1841
                return NULL;
 
1842
        Py_INCREF(&kqueue_queue_Type);
 
1843
        PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
 
1844
        
 
1845
        /* event filters */
 
1846
        PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
 
1847
        PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
 
1848
        PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
 
1849
        PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
 
1850
        PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
 
1851
#ifdef EVFILT_NETDEV
 
1852
        PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
 
1853
#endif
 
1854
        PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
 
1855
        PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
 
1856
 
 
1857
        /* event flags */
 
1858
        PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
 
1859
        PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
 
1860
        PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
 
1861
        PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
 
1862
        PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
 
1863
        PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
 
1864
 
 
1865
        PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
 
1866
        PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
 
1867
 
 
1868
        PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
 
1869
        PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
 
1870
 
 
1871
        /* READ WRITE filter flag */
 
1872
        PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
 
1873
        
 
1874
        /* VNODE filter flags  */
 
1875
        PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
 
1876
        PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
 
1877
        PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
 
1878
        PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
 
1879
        PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
 
1880
        PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
 
1881
        PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
 
1882
 
 
1883
        /* PROC filter flags  */
 
1884
        PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
 
1885
        PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
 
1886
        PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
 
1887
        PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
 
1888
        PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
 
1889
 
 
1890
        PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
 
1891
        PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
 
1892
        PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
 
1893
 
 
1894
        /* NETDEV filter flags */
 
1895
#ifdef EVFILT_NETDEV
 
1896
        PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
 
1897
        PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
 
1898
        PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
 
1899
#endif
 
1900
 
 
1901
#endif /* HAVE_KQUEUE */
 
1902
        return m;
 
1903
}