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