~justin-fathomdb/nova/justinsb-openstack-api-volumes

« back to all changes in this revision

Viewing changes to vendor/tornado/tornado/epoll.c

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2009 Facebook
 
3
 *
 
4
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 
5
 * not use this file except in compliance with the License. You may obtain
 
6
 * a copy of the License at
 
7
 *
 
8
 *     http://www.apache.org/licenses/LICENSE-2.0
 
9
 *
 
10
 * Unless required by applicable law or agreed to in writing, software
 
11
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 
12
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 
13
 * License for the specific language governing permissions and limitations
 
14
 * under the License.
 
15
 */
 
16
 
 
17
#include "Python.h"
 
18
#include <string.h>
 
19
#include <sys/epoll.h>
 
20
 
 
21
#define MAX_EVENTS 24
 
22
 
 
23
/*
 
24
 * Simple wrapper around epoll_create.
 
25
 */
 
26
static PyObject* _epoll_create(void) {
 
27
    int fd = epoll_create(MAX_EVENTS);
 
28
    if (fd == -1) {
 
29
        PyErr_SetFromErrno(PyExc_Exception);
 
30
        return NULL;
 
31
    }
 
32
 
 
33
    return PyInt_FromLong(fd);
 
34
}
 
35
 
 
36
/*
 
37
 * Simple wrapper around epoll_ctl. We throw an exception if the call fails
 
38
 * rather than returning the error code since it is an infrequent (and likely
 
39
 * catastrophic) event when it does happen.
 
40
 */
 
41
static PyObject* _epoll_ctl(PyObject* self, PyObject* args) {
 
42
    int epfd, op, fd, events;
 
43
    struct epoll_event event;
 
44
 
 
45
    if (!PyArg_ParseTuple(args, "iiiI", &epfd, &op, &fd, &events)) {
 
46
        return NULL;
 
47
    }
 
48
 
 
49
    memset(&event, 0, sizeof(event));
 
50
    event.events = events;
 
51
    event.data.fd = fd;
 
52
    if (epoll_ctl(epfd, op, fd, &event) == -1) {
 
53
        PyErr_SetFromErrno(PyExc_OSError);
 
54
        return NULL;
 
55
    }
 
56
 
 
57
    Py_INCREF(Py_None);
 
58
    return Py_None;
 
59
}
 
60
 
 
61
/*
 
62
 * Simple wrapper around epoll_wait. We return None if the call times out and
 
63
 * throw an exception if an error occurs. Otherwise, we return a list of
 
64
 * (fd, event) tuples.
 
65
 */
 
66
static PyObject* _epoll_wait(PyObject* self, PyObject* args) {
 
67
    struct epoll_event events[MAX_EVENTS];
 
68
    int epfd, timeout, num_events, i;
 
69
    PyObject* list;
 
70
    PyObject* tuple;
 
71
 
 
72
    if (!PyArg_ParseTuple(args, "ii", &epfd, &timeout)) {
 
73
        return NULL;
 
74
    }
 
75
 
 
76
    Py_BEGIN_ALLOW_THREADS
 
77
    num_events = epoll_wait(epfd, events, MAX_EVENTS, timeout);
 
78
    Py_END_ALLOW_THREADS
 
79
    if (num_events == -1) {
 
80
        PyErr_SetFromErrno(PyExc_Exception);
 
81
        return NULL;
 
82
    }
 
83
 
 
84
    list = PyList_New(num_events);
 
85
    for (i = 0; i < num_events; i++) {
 
86
        tuple = PyTuple_New(2);
 
87
        PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(events[i].data.fd));
 
88
        PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(events[i].events));
 
89
        PyList_SET_ITEM(list, i, tuple);
 
90
    }
 
91
    return list;
 
92
}
 
93
 
 
94
/*
 
95
 * Our method declararations
 
96
 */
 
97
static PyMethodDef kEpollMethods[] = {
 
98
  {"epoll_create", (PyCFunction)_epoll_create, METH_NOARGS,
 
99
   "Create an epoll file descriptor"},
 
100
  {"epoll_ctl", _epoll_ctl, METH_VARARGS,
 
101
   "Control an epoll file descriptor"},
 
102
  {"epoll_wait", _epoll_wait, METH_VARARGS,
 
103
   "Wait for events on an epoll file descriptor"},
 
104
  {NULL, NULL, 0, NULL}
 
105
};
 
106
 
 
107
/*
 
108
 * Module initialization
 
109
 */
 
110
PyMODINIT_FUNC initepoll(void) {
 
111
    Py_InitModule("epoll", kEpollMethods);
 
112
}