You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
112 lines
3.0 KiB
112 lines
3.0 KiB
/*
|
|
* Copyright 2009 Facebook
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
* not use this file except in compliance with the License. You may obtain
|
|
* a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
* License for the specific language governing permissions and limitations
|
|
* under the License.
|
|
*/
|
|
|
|
#include "Python.h"
|
|
#include <string.h>
|
|
#include <sys/epoll.h>
|
|
|
|
#define MAX_EVENTS 24
|
|
|
|
/*
|
|
* Simple wrapper around epoll_create.
|
|
*/
|
|
static PyObject* _epoll_create(void) {
|
|
int fd = epoll_create(MAX_EVENTS);
|
|
if (fd == -1) {
|
|
PyErr_SetFromErrno(PyExc_Exception);
|
|
return NULL;
|
|
}
|
|
|
|
return PyInt_FromLong(fd);
|
|
}
|
|
|
|
/*
|
|
* Simple wrapper around epoll_ctl. We throw an exception if the call fails
|
|
* rather than returning the error code since it is an infrequent (and likely
|
|
* catastrophic) event when it does happen.
|
|
*/
|
|
static PyObject* _epoll_ctl(PyObject* self, PyObject* args) {
|
|
int epfd, op, fd, events;
|
|
struct epoll_event event;
|
|
|
|
if (!PyArg_ParseTuple(args, "iiiI", &epfd, &op, &fd, &events)) {
|
|
return NULL;
|
|
}
|
|
|
|
memset(&event, 0, sizeof(event));
|
|
event.events = events;
|
|
event.data.fd = fd;
|
|
if (epoll_ctl(epfd, op, fd, &event) == -1) {
|
|
PyErr_SetFromErrno(PyExc_OSError);
|
|
return NULL;
|
|
}
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
/*
|
|
* Simple wrapper around epoll_wait. We return None if the call times out and
|
|
* throw an exception if an error occurs. Otherwise, we return a list of
|
|
* (fd, event) tuples.
|
|
*/
|
|
static PyObject* _epoll_wait(PyObject* self, PyObject* args) {
|
|
struct epoll_event events[MAX_EVENTS];
|
|
int epfd, timeout, num_events, i;
|
|
PyObject* list;
|
|
PyObject* tuple;
|
|
|
|
if (!PyArg_ParseTuple(args, "ii", &epfd, &timeout)) {
|
|
return NULL;
|
|
}
|
|
|
|
Py_BEGIN_ALLOW_THREADS
|
|
num_events = epoll_wait(epfd, events, MAX_EVENTS, timeout);
|
|
Py_END_ALLOW_THREADS
|
|
if (num_events == -1) {
|
|
PyErr_SetFromErrno(PyExc_Exception);
|
|
return NULL;
|
|
}
|
|
|
|
list = PyList_New(num_events);
|
|
for (i = 0; i < num_events; i++) {
|
|
tuple = PyTuple_New(2);
|
|
PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(events[i].data.fd));
|
|
PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(events[i].events));
|
|
PyList_SET_ITEM(list, i, tuple);
|
|
}
|
|
return list;
|
|
}
|
|
|
|
/*
|
|
* Our method declararations
|
|
*/
|
|
static PyMethodDef kEpollMethods[] = {
|
|
{"epoll_create", (PyCFunction)_epoll_create, METH_NOARGS,
|
|
"Create an epoll file descriptor"},
|
|
{"epoll_ctl", _epoll_ctl, METH_VARARGS,
|
|
"Control an epoll file descriptor"},
|
|
{"epoll_wait", _epoll_wait, METH_VARARGS,
|
|
"Wait for events on an epoll file descriptor"},
|
|
{NULL, NULL, 0, NULL}
|
|
};
|
|
|
|
/*
|
|
* Module initialization
|
|
*/
|
|
PyMODINIT_FUNC initepoll(void) {
|
|
Py_InitModule("epoll", kEpollMethods);
|
|
}
|
|
|