2 * Copyright 2009 Facebook
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
19 #include <sys/epoll.h>
24 * Simple wrapper around epoll_create.
26 static PyObject* _epoll_create(void) {
27 int fd = epoll_create(MAX_EVENTS);
29 PyErr_SetFromErrno(PyExc_Exception);
33 return PyInt_FromLong(fd);
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.
41 static PyObject* _epoll_ctl(PyObject* self, PyObject* args) {
42 int epfd, op, fd, events;
43 struct epoll_event event;
45 if (!PyArg_ParseTuple(args, "iiiI", &epfd, &op, &fd, &events)) {
49 memset(&event, 0, sizeof(event));
50 event.events = events;
52 if (epoll_ctl(epfd, op, fd, &event) == -1) {
53 PyErr_SetFromErrno(PyExc_OSError);
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
66 static PyObject* _epoll_wait(PyObject* self, PyObject* args) {
67 struct epoll_event events[MAX_EVENTS];
68 int epfd, timeout, num_events, i;
72 if (!PyArg_ParseTuple(args, "ii", &epfd, &timeout)) {
76 Py_BEGIN_ALLOW_THREADS
77 num_events = epoll_wait(epfd, events, MAX_EVENTS, timeout);
79 if (num_events == -1) {
80 PyErr_SetFromErrno(PyExc_Exception);
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);
95 * Our method declararations
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}
108 * Module initialization
110 PyMODINIT_FUNC initepoll(void) {
111 Py_InitModule("epoll", kEpollMethods);