Spaces:
Running
Running
typedef struct libevwrapper_Loop { | |
PyObject_HEAD | |
struct ev_loop *loop; | |
} libevwrapper_Loop; | |
static void | |
Loop_dealloc(libevwrapper_Loop *self) { | |
ev_loop_destroy(self->loop); | |
Py_TYPE(self)->tp_free((PyObject *)self); | |
}; | |
static PyObject* | |
Loop_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { | |
libevwrapper_Loop *self; | |
self = (libevwrapper_Loop *)type->tp_alloc(type, 0); | |
if (self != NULL) { | |
self->loop = ev_loop_new(EVBACKEND_SELECT); | |
if (!self->loop) { | |
PyErr_SetString(PyExc_Exception, "Error getting new ev loop"); | |
Py_DECREF(self); | |
return NULL; | |
} | |
} | |
return (PyObject *)self; | |
}; | |
static int | |
Loop_init(libevwrapper_Loop *self, PyObject *args, PyObject *kwds) { | |
if (!PyArg_ParseTuple(args, "")) { | |
PyErr_SetString(PyExc_TypeError, "Loop.__init__() takes no arguments"); | |
return -1; | |
} | |
return 0; | |
}; | |
static PyObject * | |
Loop_start(libevwrapper_Loop *self, PyObject *args) { | |
Py_BEGIN_ALLOW_THREADS | |
ev_run(self->loop, 0); | |
Py_END_ALLOW_THREADS | |
Py_RETURN_NONE; | |
}; | |
static PyObject * | |
Loop_unref(libevwrapper_Loop *self, PyObject *args) { | |
ev_unref(self->loop); | |
Py_RETURN_NONE; | |
} | |
static PyMethodDef Loop_methods[] = { | |
{"start", (PyCFunction)Loop_start, METH_NOARGS, "Start the event loop"}, | |
{"unref", (PyCFunction)Loop_unref, METH_NOARGS, "Unrefrence the event loop"}, | |
{NULL} /* Sentinel */ | |
}; | |
static | |
PyTypeObject libevwrapper_LoopType = { | |
PyVarObject_HEAD_INIT(NULL, 0) | |
"cassandra.io.libevwrapper.Loop",/*tp_name*/ | |
sizeof(libevwrapper_Loop), /*tp_basicsize*/ | |
0, /*tp_itemsize*/ | |
(destructor)Loop_dealloc, /*tp_dealloc*/ | |
0, /*tp_print*/ | |
0, /*tp_getattr*/ | |
0, /*tp_setattr*/ | |
0, /*tp_compare*/ | |
0, /*tp_repr*/ | |
0, /*tp_as_number*/ | |
0, /*tp_as_sequence*/ | |
0, /*tp_as_mapping*/ | |
0, /*tp_hash */ | |
0, /*tp_call*/ | |
0, /*tp_str*/ | |
0, /*tp_getattro*/ | |
0, /*tp_setattro*/ | |
0, /*tp_as_buffer*/ | |
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ | |
"Loop objects", /* tp_doc */ | |
0, /* tp_traverse */ | |
0, /* tp_clear */ | |
0, /* tp_richcompare */ | |
0, /* tp_weaklistoffset */ | |
0, /* tp_iter */ | |
0, /* tp_iternext */ | |
Loop_methods, /* tp_methods */ | |
0, /* tp_members */ | |
0, /* tp_getset */ | |
0, /* tp_base */ | |
0, /* tp_dict */ | |
0, /* tp_descr_get */ | |
0, /* tp_descr_set */ | |
0, /* tp_dictoffset */ | |
(initproc)Loop_init, /* tp_init */ | |
0, /* tp_alloc */ | |
Loop_new, /* tp_new */ | |
}; | |
typedef struct libevwrapper_IO { | |
PyObject_HEAD | |
struct ev_io io; | |
struct libevwrapper_Loop *loop; | |
PyObject *callback; | |
} libevwrapper_IO; | |
static void | |
IO_dealloc(libevwrapper_IO *self) { | |
Py_XDECREF(self->loop); | |
Py_XDECREF(self->callback); | |
Py_TYPE(self)->tp_free((PyObject *)self); | |
}; | |
static void io_callback(struct ev_loop *loop, ev_io *watcher, int revents) { | |
libevwrapper_IO *self = watcher->data; | |
PyObject *result; | |
PyGILState_STATE gstate = PyGILState_Ensure(); | |
if (revents & EV_ERROR && errno) { | |
result = PyObject_CallFunction(self->callback, "Obi", self, revents, errno); | |
} else { | |
result = PyObject_CallFunction(self->callback, "Ob", self, revents); | |
} | |
if (!result) { | |
PyErr_WriteUnraisable(self->callback); | |
} | |
Py_XDECREF(result); | |
PyGILState_Release(gstate); | |
}; | |
static int | |
IO_init(libevwrapper_IO *self, PyObject *args, PyObject *kwds) { | |
PyObject *socket; | |
PyObject *callback; | |
PyObject *loop; | |
int io_flags = 0, fd = -1; | |
struct ev_io *io = NULL; | |
if (!PyArg_ParseTuple(args, "OiOO", &socket, &io_flags, &loop, &callback)) { | |
return -1; | |
} | |
if (loop) { | |
Py_INCREF(loop); | |
self->loop = (libevwrapper_Loop *)loop; | |
} | |
if (callback) { | |
if (!PyCallable_Check(callback)) { | |
PyErr_SetString(PyExc_TypeError, "callback parameter must be callable"); | |
Py_XDECREF(loop); | |
return -1; | |
} | |
Py_INCREF(callback); | |
self->callback = callback; | |
} | |
fd = PyObject_AsFileDescriptor(socket); | |
if (fd == -1) { | |
PyErr_SetString(PyExc_TypeError, "unable to get file descriptor from socket"); | |
Py_XDECREF(callback); | |
Py_XDECREF(loop); | |
return -1; | |
} | |
io = &(self->io); | |
ev_io_init(io, io_callback, fd, io_flags); | |
self->io.data = self; | |
return 0; | |
} | |
static PyObject* | |
IO_start(libevwrapper_IO *self, PyObject *args) { | |
ev_io_start(self->loop->loop, &self->io); | |
Py_RETURN_NONE; | |
} | |
static PyObject* | |
IO_stop(libevwrapper_IO *self, PyObject *args) { | |
ev_io_stop(self->loop->loop, &self->io); | |
Py_RETURN_NONE; | |
} | |
static PyObject* | |
IO_is_active(libevwrapper_IO *self, PyObject *args) { | |
struct ev_io *io = &(self->io); | |
return PyBool_FromLong(ev_is_active(io)); | |
} | |
static PyObject* | |
IO_is_pending(libevwrapper_IO *self, PyObject *args) { | |
struct ev_io *io = &(self->io); | |
return PyBool_FromLong(ev_is_pending(io)); | |
} | |
static PyMethodDef IO_methods[] = { | |
{"start", (PyCFunction)IO_start, METH_NOARGS, "Start the watcher"}, | |
{"stop", (PyCFunction)IO_stop, METH_NOARGS, "Stop the watcher"}, | |
{"is_active", (PyCFunction)IO_is_active, METH_NOARGS, "Is the watcher active?"}, | |
{"is_pending", (PyCFunction)IO_is_pending, METH_NOARGS, "Is the watcher pending?"}, | |
{NULL} /* Sentinal */ | |
}; | |
static PyTypeObject libevwrapper_IOType = { | |
PyVarObject_HEAD_INIT(NULL, 0) | |
"cassandra.io.libevwrapper.IO", /*tp_name*/ | |
sizeof(libevwrapper_IO), /*tp_basicsize*/ | |
0, /*tp_itemsize*/ | |
(destructor)IO_dealloc, /*tp_dealloc*/ | |
0, /*tp_print*/ | |
0, /*tp_getattr*/ | |
0, /*tp_setattr*/ | |
0, /*tp_compare*/ | |
0, /*tp_repr*/ | |
0, /*tp_as_number*/ | |
0, /*tp_as_sequence*/ | |
0, /*tp_as_mapping*/ | |
0, /*tp_hash */ | |
0, /*tp_call*/ | |
0, /*tp_str*/ | |
0, /*tp_getattro*/ | |
0, /*tp_setattro*/ | |
0, /*tp_as_buffer*/ | |
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ | |
"IO objects", /* tp_doc */ | |
0, /* tp_traverse */ | |
0, /* tp_clear */ | |
0, /* tp_richcompare */ | |
0, /* tp_weaklistoffset */ | |
0, /* tp_iter */ | |
0, /* tp_iternext */ | |
IO_methods, /* tp_methods */ | |
0, /* tp_members */ | |
0, /* tp_getset */ | |
0, /* tp_base */ | |
0, /* tp_dict */ | |
0, /* tp_descr_get */ | |
0, /* tp_descr_set */ | |
0, /* tp_dictoffset */ | |
(initproc)IO_init, /* tp_init */ | |
}; | |
typedef struct libevwrapper_Async { | |
PyObject_HEAD | |
struct ev_async async; | |
struct libevwrapper_Loop *loop; | |
} libevwrapper_Async; | |
static void | |
Async_dealloc(libevwrapper_Async *self) { | |
Py_XDECREF(self->loop); | |
Py_TYPE(self)->tp_free((PyObject *)self); | |
}; | |
static void async_callback(EV_P_ ev_async *watcher, int revents) {}; | |
static int | |
Async_init(libevwrapper_Async *self, PyObject *args, PyObject *kwds) { | |
PyObject *loop; | |
static char *kwlist[] = {"loop", NULL}; | |
struct ev_async *async = NULL; | |
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &loop)) { | |
PyErr_SetString(PyExc_TypeError, "unable to get file descriptor from socket"); | |
return -1; | |
} | |
if (loop) { | |
Py_INCREF(loop); | |
self->loop = (libevwrapper_Loop *)loop; | |
} else { | |
return -1; | |
} | |
async = &(self->async); | |
ev_async_init(async, async_callback); | |
return 0; | |
}; | |
static PyObject * | |
Async_start(libevwrapper_Async *self, PyObject *args) { | |
ev_async_start(self->loop->loop, &self->async); | |
Py_RETURN_NONE; | |
} | |
static PyObject * | |
Async_send(libevwrapper_Async *self, PyObject *args) { | |
ev_async_send(self->loop->loop, &self->async); | |
Py_RETURN_NONE; | |
}; | |
static PyMethodDef Async_methods[] = { | |
{"start", (PyCFunction)Async_start, METH_NOARGS, "Start the watcher"}, | |
{"send", (PyCFunction)Async_send, METH_NOARGS, "Notify the event loop"}, | |
{NULL} /* Sentinel */ | |
}; | |
static PyTypeObject libevwrapper_AsyncType = { | |
PyVarObject_HEAD_INIT(NULL, 0) | |
"cassandra.io.libevwrapper.Async", /*tp_name*/ | |
sizeof(libevwrapper_Async), /*tp_basicsize*/ | |
0, /*tp_itemsize*/ | |
(destructor)Async_dealloc, /*tp_dealloc*/ | |
0, /*tp_print*/ | |
0, /*tp_getattr*/ | |
0, /*tp_setattr*/ | |
0, /*tp_compare*/ | |
0, /*tp_repr*/ | |
0, /*tp_as_number*/ | |
0, /*tp_as_sequence*/ | |
0, /*tp_as_mapping*/ | |
0, /*tp_hash */ | |
0, /*tp_call*/ | |
0, /*tp_str*/ | |
0, /*tp_getattro*/ | |
0, /*tp_setattro*/ | |
0, /*tp_as_buffer*/ | |
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ | |
"Async objects", /* tp_doc */ | |
0, /* tp_traverse */ | |
0, /* tp_clear */ | |
0, /* tp_richcompare */ | |
0, /* tp_weaklistoffset */ | |
0, /* tp_iter */ | |
0, /* tp_iternext */ | |
Async_methods, /* tp_methods */ | |
0, /* tp_members */ | |
0, /* tp_getset */ | |
0, /* tp_base */ | |
0, /* tp_dict */ | |
0, /* tp_descr_get */ | |
0, /* tp_descr_set */ | |
0, /* tp_dictoffset */ | |
(initproc)Async_init, /* tp_init */ | |
}; | |
typedef struct libevwrapper_Prepare { | |
PyObject_HEAD | |
struct ev_prepare prepare; | |
struct libevwrapper_Loop *loop; | |
PyObject *callback; | |
} libevwrapper_Prepare; | |
static void | |
Prepare_dealloc(libevwrapper_Prepare *self) { | |
Py_XDECREF(self->loop); | |
Py_XDECREF(self->callback); | |
Py_TYPE(self)->tp_free((PyObject *)self); | |
} | |
static void prepare_callback(struct ev_loop *loop, ev_prepare *watcher, int revents) { | |
libevwrapper_Prepare *self = watcher->data; | |
PyObject *result = NULL; | |
PyGILState_STATE gstate; | |
gstate = PyGILState_Ensure(); | |
result = PyObject_CallFunction(self->callback, "O", self); | |
if (!result) { | |
PyErr_WriteUnraisable(self->callback); | |
} | |
Py_XDECREF(result); | |
PyGILState_Release(gstate); | |
} | |
static int | |
Prepare_init(libevwrapper_Prepare *self, PyObject *args, PyObject *kwds) { | |
PyObject *callback; | |
PyObject *loop; | |
struct ev_prepare *prepare = NULL; | |
if (!PyArg_ParseTuple(args, "OO", &loop, &callback)) { | |
return -1; | |
} | |
if (loop) { | |
Py_INCREF(loop); | |
self->loop = (libevwrapper_Loop *)loop; | |
} else { | |
return -1; | |
} | |
if (callback) { | |
if (!PyCallable_Check(callback)) { | |
PyErr_SetString(PyExc_TypeError, "callback parameter must be callable"); | |
Py_XDECREF(loop); | |
return -1; | |
} | |
Py_INCREF(callback); | |
self->callback = callback; | |
} | |
prepare = &(self->prepare); | |
ev_prepare_init(prepare, prepare_callback); | |
self->prepare.data = self; | |
return 0; | |
} | |
static PyObject * | |
Prepare_start(libevwrapper_Prepare *self, PyObject *args) { | |
ev_prepare_start(self->loop->loop, &self->prepare); | |
Py_RETURN_NONE; | |
} | |
static PyObject * | |
Prepare_stop(libevwrapper_Prepare *self, PyObject *args) { | |
ev_prepare_stop(self->loop->loop, &self->prepare); | |
Py_RETURN_NONE; | |
} | |
static PyMethodDef Prepare_methods[] = { | |
{"start", (PyCFunction)Prepare_start, METH_NOARGS, "Start the Prepare watcher"}, | |
{"stop", (PyCFunction)Prepare_stop, METH_NOARGS, "Stop the Prepare watcher"}, | |
{NULL} /* Sentinal */ | |
}; | |
static PyTypeObject libevwrapper_PrepareType = { | |
PyVarObject_HEAD_INIT(NULL, 0) | |
"cassandra.io.libevwrapper.Prepare", /*tp_name*/ | |
sizeof(libevwrapper_Prepare), /*tp_basicsize*/ | |
0, /*tp_itemsize*/ | |
(destructor)Prepare_dealloc, /*tp_dealloc*/ | |
0, /*tp_print*/ | |
0, /*tp_getattr*/ | |
0, /*tp_setattr*/ | |
0, /*tp_compare*/ | |
0, /*tp_repr*/ | |
0, /*tp_as_number*/ | |
0, /*tp_as_sequence*/ | |
0, /*tp_as_mapping*/ | |
0, /*tp_hash */ | |
0, /*tp_call*/ | |
0, /*tp_str*/ | |
0, /*tp_getattro*/ | |
0, /*tp_setattro*/ | |
0, /*tp_as_buffer*/ | |
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ | |
"Prepare objects", /* tp_doc */ | |
0, /* tp_traverse */ | |
0, /* tp_clear */ | |
0, /* tp_richcompare */ | |
0, /* tp_weaklistoffset */ | |
0, /* tp_iter */ | |
0, /* tp_iternext */ | |
Prepare_methods, /* tp_methods */ | |
0, /* tp_members */ | |
0, /* tp_getset */ | |
0, /* tp_base */ | |
0, /* tp_dict */ | |
0, /* tp_descr_get */ | |
0, /* tp_descr_set */ | |
0, /* tp_dictoffset */ | |
(initproc)Prepare_init, /* tp_init */ | |
}; | |
typedef struct libevwrapper_Timer { | |
PyObject_HEAD | |
struct ev_timer timer; | |
struct libevwrapper_Loop *loop; | |
PyObject *callback; | |
} libevwrapper_Timer; | |
static void | |
Timer_dealloc(libevwrapper_Timer *self) { | |
Py_XDECREF(self->loop); | |
Py_XDECREF(self->callback); | |
Py_TYPE(self)->tp_free((PyObject *)self); | |
} | |
static void timer_callback(struct ev_loop *loop, ev_timer *watcher, int revents) { | |
libevwrapper_Timer *self = watcher->data; | |
PyObject *result = NULL; | |
PyGILState_STATE gstate; | |
gstate = PyGILState_Ensure(); | |
result = PyObject_CallFunction(self->callback, NULL); | |
if (!result) { | |
PyErr_WriteUnraisable(self->callback); | |
} | |
Py_XDECREF(result); | |
PyGILState_Release(gstate); | |
} | |
static int | |
Timer_init(libevwrapper_Timer *self, PyObject *args, PyObject *kwds) { | |
PyObject *callback; | |
PyObject *loop; | |
if (!PyArg_ParseTuple(args, "OO", &loop, &callback)) { | |
return -1; | |
} | |
if (loop) { | |
Py_INCREF(loop); | |
self->loop = (libevwrapper_Loop *)loop; | |
} else { | |
return -1; | |
} | |
if (callback) { | |
if (!PyCallable_Check(callback)) { | |
PyErr_SetString(PyExc_TypeError, "callback parameter must be callable"); | |
Py_XDECREF(loop); | |
return -1; | |
} | |
Py_INCREF(callback); | |
self->callback = callback; | |
} | |
ev_init(&self->timer, timer_callback); | |
self->timer.data = self; | |
return 0; | |
} | |
static PyObject * | |
Timer_start(libevwrapper_Timer *self, PyObject *args) { | |
double timeout; | |
if (!PyArg_ParseTuple(args, "d", &timeout)) { | |
return NULL; | |
} | |
/* some tiny non-zero number to avoid zero, and | |
make it run immediately for negative timeouts */ | |
self->timer.repeat = fmax(timeout, 0.000000001); | |
ev_timer_again(self->loop->loop, &self->timer); | |
Py_RETURN_NONE; | |
} | |
static PyObject * | |
Timer_stop(libevwrapper_Timer *self, PyObject *args) { | |
ev_timer_stop(self->loop->loop, &self->timer); | |
Py_RETURN_NONE; | |
} | |
static PyMethodDef Timer_methods[] = { | |
{"start", (PyCFunction)Timer_start, METH_VARARGS, "Start the Timer watcher"}, | |
{"stop", (PyCFunction)Timer_stop, METH_NOARGS, "Stop the Timer watcher"}, | |
{NULL} /* Sentinal */ | |
}; | |
static PyTypeObject libevwrapper_TimerType = { | |
PyVarObject_HEAD_INIT(NULL, 0) | |
"cassandra.io.libevwrapper.Timer", /*tp_name*/ | |
sizeof(libevwrapper_Timer), /*tp_basicsize*/ | |
0, /*tp_itemsize*/ | |
(destructor)Timer_dealloc, /*tp_dealloc*/ | |
0, /*tp_print*/ | |
0, /*tp_getattr*/ | |
0, /*tp_setattr*/ | |
0, /*tp_compare*/ | |
0, /*tp_repr*/ | |
0, /*tp_as_number*/ | |
0, /*tp_as_sequence*/ | |
0, /*tp_as_mapping*/ | |
0, /*tp_hash */ | |
0, /*tp_call*/ | |
0, /*tp_str*/ | |
0, /*tp_getattro*/ | |
0, /*tp_setattro*/ | |
0, /*tp_as_buffer*/ | |
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ | |
"Timer objects", /* tp_doc */ | |
0, /* tp_traverse */ | |
0, /* tp_clear */ | |
0, /* tp_richcompare */ | |
0, /* tp_weaklistoffset */ | |
0, /* tp_iter */ | |
0, /* tp_iternext */ | |
Timer_methods, /* tp_methods */ | |
0, /* tp_members */ | |
0, /* tp_getset */ | |
0, /* tp_base */ | |
0, /* tp_dict */ | |
0, /* tp_descr_get */ | |
0, /* tp_descr_set */ | |
0, /* tp_dictoffset */ | |
(initproc)Timer_init, /* tp_init */ | |
}; | |
static PyMethodDef module_methods[] = { | |
{NULL} /* Sentinal */ | |
}; | |
PyDoc_STRVAR(module_doc, | |
"libev wrapper methods"); | |
static struct PyModuleDef moduledef = { | |
PyModuleDef_HEAD_INIT, | |
"libevwrapper", | |
module_doc, | |
-1, | |
module_methods, | |
NULL, | |
NULL, | |
NULL, | |
NULL | |
}; | |
PyObject * | |
PyInit_libevwrapper(void) | |
void | |
initlibevwrapper(void) | |
{ | |
PyObject *module = NULL; | |
if (PyType_Ready(&libevwrapper_LoopType) < 0) | |
INITERROR; | |
libevwrapper_IOType.tp_new = PyType_GenericNew; | |
if (PyType_Ready(&libevwrapper_IOType) < 0) | |
INITERROR; | |
libevwrapper_PrepareType.tp_new = PyType_GenericNew; | |
if (PyType_Ready(&libevwrapper_PrepareType) < 0) | |
INITERROR; | |
libevwrapper_AsyncType.tp_new = PyType_GenericNew; | |
if (PyType_Ready(&libevwrapper_AsyncType) < 0) | |
INITERROR; | |
libevwrapper_TimerType.tp_new = PyType_GenericNew; | |
if (PyType_Ready(&libevwrapper_TimerType) < 0) | |
INITERROR; | |
module = PyModule_Create(&moduledef); | |
module = Py_InitModule3("libevwrapper", module_methods, module_doc); | |
if (module == NULL) | |
INITERROR; | |
if (PyModule_AddIntConstant(module, "EV_READ", EV_READ) == -1) | |
INITERROR; | |
if (PyModule_AddIntConstant(module, "EV_WRITE", EV_WRITE) == -1) | |
INITERROR; | |
if (PyModule_AddIntConstant(module, "EV_ERROR", EV_ERROR) == -1) | |
INITERROR; | |
Py_INCREF(&libevwrapper_LoopType); | |
if (PyModule_AddObject(module, "Loop", (PyObject *)&libevwrapper_LoopType) == -1) | |
INITERROR; | |
Py_INCREF(&libevwrapper_IOType); | |
if (PyModule_AddObject(module, "IO", (PyObject *)&libevwrapper_IOType) == -1) | |
INITERROR; | |
Py_INCREF(&libevwrapper_PrepareType); | |
if (PyModule_AddObject(module, "Prepare", (PyObject *)&libevwrapper_PrepareType) == -1) | |
INITERROR; | |
Py_INCREF(&libevwrapper_AsyncType); | |
if (PyModule_AddObject(module, "Async", (PyObject *)&libevwrapper_AsyncType) == -1) | |
INITERROR; | |
Py_INCREF(&libevwrapper_TimerType); | |
if (PyModule_AddObject(module, "Timer", (PyObject *)&libevwrapper_TimerType) == -1) | |
INITERROR; | |
if (!PyEval_ThreadsInitialized()) { | |
PyEval_InitThreads(); | |
} | |
return module; | |
} | |