Allow user-supplied tracer callback.

This commit is contained in:
Joris Vink 2018-11-29 09:51:24 +01:00
parent b400fdcd9f
commit d9f543ef5b
2 changed files with 35 additions and 1 deletions

View File

@ -39,6 +39,7 @@ static PyObject *python_kore_bind(PyObject *, PyObject *);
static PyObject *python_kore_timer(PyObject *, PyObject *); static PyObject *python_kore_timer(PyObject *, PyObject *);
static PyObject *python_kore_fatal(PyObject *, PyObject *); static PyObject *python_kore_fatal(PyObject *, PyObject *);
static PyObject *python_kore_queue(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_gather(PyObject *, PyObject *);
static PyObject *python_kore_fatalx(PyObject *, PyObject *); static PyObject *python_kore_fatalx(PyObject *, PyObject *);
static PyObject *python_kore_suspend(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("bind", python_kore_bind, METH_VARARGS),
METHOD("timer", python_kore_timer, METH_VARARGS), METHOD("timer", python_kore_timer, METH_VARARGS),
METHOD("queue", python_kore_queue, METH_VARARGS), METHOD("queue", python_kore_queue, METH_VARARGS),
METHOD("tracer", python_kore_tracer, METH_VARARGS),
METHOD("gather", python_kore_gather, METH_VARARGS), METHOD("gather", python_kore_gather, METH_VARARGS),
METHOD("fatal", python_kore_fatal, METH_VARARGS), METHOD("fatal", python_kore_fatal, METH_VARARGS),
METHOD("fatalx", python_kore_fatalx, METH_VARARGS), METHOD("fatalx", python_kore_fatalx, METH_VARARGS),

View File

@ -171,6 +171,7 @@ extern const char *__progname;
/* XXX */ /* XXX */
static struct python_coro *coro_running = NULL; static struct python_coro *coro_running = NULL;
static PyObject *python_tracer = NULL;
void void
kore_python_init(void) kore_python_init(void)
@ -287,7 +288,7 @@ void
kore_python_log_error(const char *function) kore_python_log_error(const char *function)
{ {
const char *sval; const char *sval;
PyObject *repr, *type, *value, *traceback; PyObject *ret, *repr, *type, *value, *traceback;
if (!PyErr_Occurred() || PyErr_ExceptionMatches(PyExc_StopIteration)) if (!PyErr_Occurred() || PyErr_ExceptionMatches(PyExc_StopIteration))
return; return;
@ -310,6 +311,13 @@ kore_python_log_error(const char *function)
*/ */
if (coro_running != NULL && coro_running->gatherop != NULL) { if (coro_running != NULL && coro_running->gatherop != NULL) {
PyErr_SetObject(PyExc_StopIteration, value); 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 { } else {
if ((repr = PyObject_Repr(value)) == NULL) if ((repr = PyObject_Repr(value)) == NULL)
sval = "unknown"; sval = "unknown";
@ -1027,6 +1035,30 @@ python_kore_queue(PyObject *self, PyObject *args)
return ((PyObject *)queue); return ((PyObject *)queue);
} }
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 * static PyObject *
python_kore_gather(PyObject *self, PyObject *args) python_kore_gather(PyObject *self, PyObject *args)
{ {