kore

a fork of the worlds most advanced web framework
Log | Files | Refs | README | LICENSE

commit d9f543ef5ba62ad1a7ba2a652f6edd847468989a
parent b400fdcd9f5f80a3167870e8eab1206fc59c9190
Author: Joris Vink <joris@coders.se>
Date:   Thu, 29 Nov 2018 09:51:24 +0100

Allow user-supplied tracer callback.

Diffstat:
Minclude/kore/python_methods.h | 2++
Msrc/python.c | 34+++++++++++++++++++++++++++++++++-
2 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/include/kore/python_methods.h b/include/kore/python_methods.h @@ -39,6 +39,7 @@ static PyObject *python_kore_bind(PyObject *, PyObject *); static PyObject *python_kore_timer(PyObject *, PyObject *); static PyObject *python_kore_fatal(PyObject *, PyObject *); static PyObject *python_kore_queue(PyObject *, PyObject *); +static PyObject *python_kore_tracer(PyObject *, PyObject *); static PyObject *python_kore_gather(PyObject *, PyObject *); static PyObject *python_kore_fatalx(PyObject *, PyObject *); static PyObject *python_kore_suspend(PyObject *, PyObject *); @@ -66,6 +67,7 @@ static struct PyMethodDef pykore_methods[] = { METHOD("bind", python_kore_bind, METH_VARARGS), METHOD("timer", python_kore_timer, METH_VARARGS), METHOD("queue", python_kore_queue, METH_VARARGS), + METHOD("tracer", python_kore_tracer, METH_VARARGS), METHOD("gather", python_kore_gather, METH_VARARGS), METHOD("fatal", python_kore_fatal, METH_VARARGS), METHOD("fatalx", python_kore_fatalx, METH_VARARGS), diff --git a/src/python.c b/src/python.c @@ -171,6 +171,7 @@ extern const char *__progname; /* XXX */ static struct python_coro *coro_running = NULL; +static PyObject *python_tracer = NULL; void kore_python_init(void) @@ -287,7 +288,7 @@ void kore_python_log_error(const char *function) { const char *sval; - PyObject *repr, *type, *value, *traceback; + PyObject *ret, *repr, *type, *value, *traceback; if (!PyErr_Occurred() || PyErr_ExceptionMatches(PyExc_StopIteration)) return; @@ -310,6 +311,13 @@ kore_python_log_error(const char *function) */ if (coro_running != NULL && coro_running->gatherop != NULL) { PyErr_SetObject(PyExc_StopIteration, value); + } else if (python_tracer != NULL) { + /* + * Call the user-supplied tracer callback. + */ + ret = PyObject_CallFunctionObjArgs(python_tracer, + type, value, traceback, NULL); + Py_XDECREF(ret); } else { if ((repr = PyObject_Repr(value)) == NULL) sval = "unknown"; @@ -1028,6 +1036,30 @@ python_kore_queue(PyObject *self, PyObject *args) } static PyObject * +python_kore_tracer(PyObject *self, PyObject *args) +{ + PyObject *obj; + + if (python_tracer != NULL) { + PyErr_SetString(PyExc_RuntimeError, "tracer already set"); + return (NULL); + } + + if (!PyArg_ParseTuple(args, "O", &obj)) + return (NULL); + + if (!PyCallable_Check(obj)) { + PyErr_SetString(PyExc_RuntimeError, "object not callable"); + Py_DECREF(obj); + return (NULL); + } + + python_tracer = obj; + + Py_RETURN_TRUE; +} + +static PyObject * python_kore_gather(PyObject *self, PyObject *args) { struct pygather_op *op;