libevwrapper.py is using atexit module to do it's cleanup of global loop
from time to time we see the following crashes during python shutdown:
for years we had a workaround of some sort in SCT that was clearing the atexit hooks, blindly.
we removed it since it breaking other part that SCT or other part are using atexit.
and now we are getting this crash from time to time.
there two things that I think needs to improve:
- ability to stop the libev loop, so we won't get into case it wakes up during python shutdown
- refactor code to no use global loop and do cleanup directly without atexit
complete vibe code example of part one, it got compiled.
but didn't have a clear path (nor time) to test it
diff --git a/cassandra/io/libevwrapper.c b/cassandra/io/libevwrapper.c
index f32504fa3..0689bf3b9 100644
--- a/cassandra/io/libevwrapper.c
+++ b/cassandra/io/libevwrapper.c
@@ -6,6 +6,7 @@
typedef struct libevwrapper_Loop {
PyObject_HEAD
struct ev_loop *loop;
+ ev_async async_watcher;
} libevwrapper_Loop;
static void
@@ -30,12 +31,24 @@ Loop_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
return (PyObject *)self;
};
+static void async_stop_cb(EV_P_ ev_async *w, int revents) {
+ ev_break(EV_A_ EVBREAK_ALL);
+}
+
+static PyObject *
+Loop_stop(libevwrapper_Loop *self, PyObject *args) {
+ ev_async_send(self->loop, &self->async_watcher);
+ Py_RETURN_NONE;
+}
+
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;
}
+ ev_async_init(&self->async_watcher, async_stop_cb);
+ ev_async_start(self->loop, &self->async_watcher);
return 0;
};
@@ -56,6 +69,7 @@ Loop_unref(libevwrapper_Loop *self, PyObject *args) {
static PyMethodDef Loop_methods[] = {
{"start", (PyCFunction)Loop_start, METH_NOARGS, "Start the event loop"},
{"unref", (PyCFunction)Loop_unref, METH_NOARGS, "Unrefrence the event loop"},
+ {"stop", (PyCFunction)Loop_stop, METH_NOARGS, "Stop the event loop from any thread"},
{NULL} /* Sentinel */
};
libevwrapper.py is using atexit module to do it's cleanup of global loop
from time to time we see the following crashes during python shutdown:
for years we had a workaround of some sort in SCT that was clearing the atexit hooks, blindly.
we removed it since it breaking other part that SCT or other part are using atexit.
and now we are getting this crash from time to time.
there two things that I think needs to improve:
complete vibe code example of part one, it got compiled.
but didn't have a clear path (nor time) to test it