epoll.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2009 Facebook
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License"); you may
00005  * not use this file except in compliance with the License. You may obtain
00006  * a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00012  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
00013  * License for the specific language governing permissions and limitations
00014  * under the License.
00015  */
00016 
00017 #include "Python.h"
00018 #include <string.h>
00019 #include <sys/epoll.h>
00020 
00021 #define MAX_EVENTS 24
00022 
00023 /*
00024  * Simple wrapper around epoll_create.
00025  */
00026 static PyObject* _epoll_create(void) {
00027     int fd = epoll_create(MAX_EVENTS);
00028     if (fd == -1) {
00029         PyErr_SetFromErrno(PyExc_Exception);
00030         return NULL;
00031     }
00032 
00033     return PyInt_FromLong(fd);
00034 }
00035 
00036 /*
00037  * Simple wrapper around epoll_ctl. We throw an exception if the call fails
00038  * rather than returning the error code since it is an infrequent (and likely
00039  * catastrophic) event when it does happen.
00040  */
00041 static PyObject* _epoll_ctl(PyObject* self, PyObject* args) {
00042     int epfd, op, fd, events;
00043     struct epoll_event event;
00044 
00045     if (!PyArg_ParseTuple(args, "iiiI", &epfd, &op, &fd, &events)) {
00046         return NULL;
00047     }
00048 
00049     memset(&event, 0, sizeof(event));
00050     event.events = events;
00051     event.data.fd = fd;
00052     if (epoll_ctl(epfd, op, fd, &event) == -1) {
00053         PyErr_SetFromErrno(PyExc_OSError);
00054         return NULL;
00055     }
00056 
00057     Py_INCREF(Py_None);
00058     return Py_None;
00059 }
00060 
00061 /*
00062  * Simple wrapper around epoll_wait. We return None if the call times out and
00063  * throw an exception if an error occurs. Otherwise, we return a list of
00064  * (fd, event) tuples.
00065  */
00066 static PyObject* _epoll_wait(PyObject* self, PyObject* args) {
00067     struct epoll_event events[MAX_EVENTS];
00068     int epfd, timeout, num_events, i;
00069     PyObject* list;
00070     PyObject* tuple;
00071 
00072     if (!PyArg_ParseTuple(args, "ii", &epfd, &timeout)) {
00073         return NULL;
00074     }
00075 
00076     Py_BEGIN_ALLOW_THREADS
00077     num_events = epoll_wait(epfd, events, MAX_EVENTS, timeout);
00078     Py_END_ALLOW_THREADS
00079     if (num_events == -1) {
00080         PyErr_SetFromErrno(PyExc_Exception);
00081         return NULL;
00082     }
00083 
00084     list = PyList_New(num_events);
00085     for (i = 0; i < num_events; i++) {
00086         tuple = PyTuple_New(2);
00087         PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(events[i].data.fd));
00088         PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(events[i].events));
00089         PyList_SET_ITEM(list, i, tuple);
00090     }
00091     return list;
00092 }
00093 
00094 /*
00095  * Our method declararations
00096  */
00097 static PyMethodDef kEpollMethods[] = {
00098   {"epoll_create", (PyCFunction)_epoll_create, METH_NOARGS,
00099    "Create an epoll file descriptor"},
00100   {"epoll_ctl", _epoll_ctl, METH_VARARGS,
00101    "Control an epoll file descriptor"},
00102   {"epoll_wait", _epoll_wait, METH_VARARGS,
00103    "Wait for events on an epoll file descriptor"},
00104   {NULL, NULL, 0, NULL}
00105 };
00106 
00107 /*
00108  * Module initialization
00109  */
00110 PyMODINIT_FUNC initepoll(void) {
00111     Py_InitModule("epoll", kEpollMethods);
00112 }


roswww
Author(s): Jonathan Mace
autogenerated on Thu Jan 2 2014 11:53:30