Browse Source

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
rdb 4 years ago
parent
commit
2b3f2bb98c
1 changed files with 15 additions and 2 deletions
  1. 15 2
      panda/src/event/asyncFuture_ext.cxx

+ 15 - 2
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
     }