From 2b3f2bb98c319282f68a1c513609c6b8cde39003 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 1 Mar 2021 11:20:16 +0100 Subject: [PATCH] event: gather() should schedule coroutines with task manager This matches the behaviour of asyncio. It schedules with the current task's manager and chain. If no current manager is found, it prints a warning. (The user can just add the coroutine to a task manager themselves and pass the resulting task into gather() if needed.) See discussion here: https://discourse.panda3d.org/t/task-gather-does-not-seem-to-work/27313 --- panda/src/event/asyncFuture_ext.cxx | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/panda/src/event/asyncFuture_ext.cxx b/panda/src/event/asyncFuture_ext.cxx index b11f0232ca..1d926f0d3c 100644 --- a/panda/src/event/asyncFuture_ext.cxx +++ b/panda/src/event/asyncFuture_ext.cxx @@ -16,6 +16,8 @@ #include "eventParameter.h" #include "paramValue.h" #include "pythonTask.h" +#include "asyncTaskManager.h" +#include "config_event.h" #ifdef HAVE_PYTHON @@ -297,8 +299,19 @@ gather(PyObject *args) { #if PY_VERSION_HEX >= 0x03050000 } else if (PyCoro_CheckExact(item)) { // We allow passing in a coroutine instead of a future. This causes it - // to be scheduled as a task. - futures.push_back(new PythonTask(item)); + // to be scheduled as a task on the current task manager. + PT(AsyncTask) task = new PythonTask(item); + Thread *current_thread = Thread::get_current_thread(); + AsyncTask *current_task = (AsyncTask *)current_thread->get_current_task(); + if (current_task != nullptr) { + task->set_task_chain(current_task->get_task_chain()); + current_task->get_manager()->add(task); + } + else { + event_cat.warning() + << "gather() with coroutine not called from within a task; not scheduling with task manager.\n"; + } + futures.push_back(task); continue; #endif }