inherit from native asyncio.Task */
PyObject *non_asyncio_tasks;
- /* Set containing all eagerly executing tasks. */
- PyObject *eager_tasks;
+ /* Set containing all 3rd party eagerly executing tasks which don't
+ inherit from native asyncio.Task */
+ PyObject *non_asyncio_eager_tasks;
/* An isinstance type cache for the 'is_coroutine()' function. */
PyObject *iscoroutine_typecache;
llist_insert_tail(head, &task->task_node);
}
-static int
-register_eager_task(asyncio_state *state, PyObject *task)
-{
- return PySet_Add(state->eager_tasks, task);
-}
-
static inline void
unregister_task_safe(TaskObj *task)
{
#endif
}
-static int
-unregister_eager_task(asyncio_state *state, PyObject *task)
-{
- return PySet_Discard(state->eager_tasks, task);
-}
-
static int
enter_task(PyObject *loop, PyObject *task)
{
if (prevtask == NULL) {
return -1;
}
-
- if (register_eager_task(state, (PyObject *)task) == -1) {
- Py_DECREF(prevtask);
- return -1;
- }
+ // register the task into the linked list of tasks
+ // if the task completes eagerly (without suspending) then it will unregister itself
+ // in future_schedule_callbacks when done, otherwise
+ // it will continue as a regular (non-eager) asyncio task
+ register_task(task);
if (PyContext_Enter(task->task_context) == -1) {
Py_DECREF(prevtask);
Py_DECREF(curtask);
}
- if (unregister_eager_task(state, (PyObject *)task) == -1) {
- retval = -1;
- }
-
if (PyContext_Exit(task->task_context) == -1) {
retval = -1;
}
- if (task->task_state == STATE_PENDING) {
- register_task(task);
- } else {
+ if (task->task_state != STATE_PENDING) {
// This seems to really help performance on pyperformance benchmarks
clear_task_coro(task);
}
/*[clinic end generated code: output=dfe1d45367c73f1a input=237f684683398c51]*/
{
asyncio_state *state = get_asyncio_state(module);
- if (register_eager_task(state, task) < 0) {
+
+ if (Task_Check(state, task)) {
+ // task is an asyncio.Task instance or subclass, use efficient
+ // linked-list implementation.
+ register_task((TaskObj *)task);
+ Py_RETURN_NONE;
+ }
+
+ if (PySet_Add(state->non_asyncio_eager_tasks, task) < 0) {
return NULL;
}
+
Py_RETURN_NONE;
}
/*[clinic end generated code: output=a426922bd07f23d1 input=9d07401ef14ee048]*/
{
asyncio_state *state = get_asyncio_state(module);
- if (unregister_eager_task(state, task) < 0) {
+ if (Task_Check(state, task)) {
+ // task is an asyncio.Task instance or subclass, use efficient
+ // linked-list implementation.
+ unregister_task((TaskObj *)task);
+ Py_RETURN_NONE;
+ }
+
+ if (PySet_Discard(state->non_asyncio_eager_tasks, task) < 0) {
return NULL;
}
+
Py_RETURN_NONE;
}
Py_DECREF(loop);
return NULL;
}
- if (PyList_Extend(tasks, state->eager_tasks) < 0) {
+ if (PyList_Extend(tasks, state->non_asyncio_eager_tasks) < 0) {
Py_DECREF(tasks);
Py_DECREF(loop);
return NULL;
Py_VISIT(state->asyncio_CancelledError);
Py_VISIT(state->non_asyncio_tasks);
- Py_VISIT(state->eager_tasks);
+ Py_VISIT(state->non_asyncio_eager_tasks);
Py_VISIT(state->iscoroutine_typecache);
Py_VISIT(state->context_kwname);
Py_CLEAR(state->asyncio_CancelledError);
Py_CLEAR(state->non_asyncio_tasks);
- Py_CLEAR(state->eager_tasks);
+ Py_CLEAR(state->non_asyncio_eager_tasks);
Py_CLEAR(state->iscoroutine_typecache);
Py_CLEAR(state->context_kwname);
goto fail;
}
- state->eager_tasks = PySet_New(NULL);
- if (state->eager_tasks == NULL) {
+ state->non_asyncio_eager_tasks = PySet_New(NULL);
+ if (state->non_asyncio_eager_tasks == NULL) {
goto fail;
}
return -1;
}
- if (PyModule_AddObjectRef(mod, "_scheduled_tasks", state->non_asyncio_tasks) < 0) {
- return -1;
- }
-
- if (PyModule_AddObjectRef(mod, "_eager_tasks", state->eager_tasks) < 0) {
- return -1;
- }
-
return 0;
}