kore

An easy to use, scalable and secure web application framework for writing web APIs in C.
Commits | Files | Refs | README | LICENSE | git clone https://git.kore.io/kore.git

commit 95506204e80a8029f3274365b7f00842ce9c1e94
parent b107485ea4fa39304f2a0cb245cf443c800f1bbe
Author: Joris Vink <joris@coders.se>
Date:   Tue, 17 Sep 2019 20:04:35 +0200

Add kore.task_kill() to the python api.

Allows killing of coroutines, given their task id.

The kore.task_create() method now returns the task id for a newly
created task to the caller.

While here, change the coroutine task id to a uint32 from uint64.
There is no need for it to be 64bit. (famous last words)

Diffstat:
include/kore/python_methods.h | 5++++-
src/python.c | 45++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 44 insertions(+), 6 deletions(-)

diff --git a/include/kore/python_methods.h b/include/kore/python_methods.h @@ -18,8 +18,9 @@ #define CORO_STATE_SUSPENDED 2 struct python_coro { - u_int64_t id; + u_int32_t id; int state; + int killed; PyObject *obj; #if defined(PYTHON_CORO_TRACE) char *name; @@ -51,6 +52,7 @@ static PyObject *python_kore_suspend(PyObject *, PyObject *); static PyObject *python_kore_shutdown(PyObject *, PyObject *); static PyObject *python_kore_coroname(PyObject *, PyObject *); static PyObject *python_kore_bind_unix(PyObject *, PyObject *); +static PyObject *python_kore_task_kill(PyObject *, PyObject *); static PyObject *python_kore_prerequest(PyObject *, PyObject *); static PyObject *python_kore_task_create(PyObject *, PyObject *); static PyObject *python_kore_socket_wrap(PyObject *, PyObject *); @@ -91,6 +93,7 @@ static struct PyMethodDef pykore_methods[] = { METHOD("suspend", python_kore_suspend, METH_VARARGS), METHOD("shutdown", python_kore_shutdown, METH_NOARGS), METHOD("coroname", python_kore_coroname, METH_VARARGS), + METHOD("task_kill", python_kore_task_kill, METH_VARARGS), METHOD("bind_unix", python_kore_bind_unix, METH_VARARGS), METHOD("prerequest", python_kore_prerequest, METH_VARARGS), METHOD("task_create", python_kore_task_create, METH_VARARGS), diff --git a/src/python.c b/src/python.c @@ -321,7 +321,7 @@ kore_python_coro_delete(void *obj) coro_count--; #if defined(PYTHON_CORO_TRACE) - python_coro_trace("deleted", coro); + python_coro_trace(coro->killed ? "killed" : "deleted", coro); #endif coro_running = coro; @@ -567,6 +567,7 @@ python_coro_create(PyObject *obj, struct http_request *req) coro->exception_msg = NULL; coro->obj = obj; + coro->killed = 0; coro->request = req; coro->id = coro_id++; coro->state = CORO_STATE_RUNNABLE; @@ -696,7 +697,7 @@ python_coro_trace(const char *label, struct python_coro *coro) kore_log(LOG_NOTICE, "coro '%s' %s <%s> @ [%s:%d]", coro->name, label, func, fname, line); } else { - kore_log(LOG_NOTICE, "coro %" PRIu64 " %s <%s> @ [%s:%d]", + kore_log(LOG_NOTICE, "coro %u %s <%s> @ [%s:%d]", coro->id, label, func, fname, line); } } @@ -1246,6 +1247,7 @@ static PyObject * python_kore_task_create(PyObject *self, PyObject *args) { PyObject *obj; + struct python_coro *coro; if (!PyArg_ParseTuple(args, "O", &obj)) return (NULL); @@ -1253,10 +1255,43 @@ python_kore_task_create(PyObject *self, PyObject *args) if (!PyCoro_CheckExact(obj)) fatal("%s: object is not a coroutine", __func__); - python_coro_create(obj, NULL); + coro = python_coro_create(obj, NULL); Py_INCREF(obj); - Py_RETURN_NONE; + return (PyLong_FromUnsignedLong(coro->id)); +} + +static PyObject * +python_kore_task_kill(PyObject *self, PyObject *args) +{ + u_int32_t id; + struct python_coro *coro, *active; + + if (!PyArg_ParseTuple(args, "I", &id)) + return (NULL); + + /* Remember active coro, as delete sets coro_running to NULL. */ + active = coro_running; + + TAILQ_FOREACH(coro, &coro_runnable, list) { + if (coro->id == id) { + coro->killed++; + kore_python_coro_delete(coro); + coro_running = active; + Py_RETURN_TRUE; + } + } + + TAILQ_FOREACH(coro, &coro_suspended, list) { + if (coro->id == id) { + coro->killed++; + kore_python_coro_delete(coro); + coro_running = active; + Py_RETURN_TRUE; + } + } + + Py_RETURN_FALSE; } static PyObject * @@ -3161,7 +3196,7 @@ pygather_reap_coro(struct pygather_op *op, struct python_coro *reap) } if (coro == NULL) - fatal("coroutine %" PRIu64 " not found in gather", reap->id); + fatal("coroutine %u not found in gather", reap->id); op->running--; if (op->running < 0)