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:
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;