@@ -143,8 +143,9 @@ typedef struct {
143143 inherit from native asyncio.Task */
144144 PyObject * non_asyncio_tasks ;
145145
146- /* Set containing all eagerly executing tasks. */
147- PyObject * eager_tasks ;
146+ /* Set containing all 3rd party eagerly executing tasks which don't
147+ inherit from native asyncio.Task */
148+ PyObject * non_asyncio_eager_tasks ;
148149
149150 /* An isinstance type cache for the 'is_coroutine()' function. */
150151 PyObject * iscoroutine_typecache ;
@@ -2180,12 +2181,6 @@ register_task(TaskObj *task)
21802181 llist_insert_tail (head , & task -> task_node );
21812182}
21822183
2183- static int
2184- register_eager_task (asyncio_state * state , PyObject * task )
2185- {
2186- return PySet_Add (state -> eager_tasks , task );
2187- }
2188-
21892184static inline void
21902185unregister_task_safe (TaskObj * task )
21912186{
@@ -2219,12 +2214,6 @@ unregister_task(TaskObj *task)
22192214#endif
22202215}
22212216
2222- static int
2223- unregister_eager_task (asyncio_state * state , PyObject * task )
2224- {
2225- return PySet_Discard (state -> eager_tasks , task );
2226- }
2227-
22282217static int
22292218enter_task (PyObject * loop , PyObject * task )
22302219{
@@ -3472,11 +3461,11 @@ task_eager_start(asyncio_state *state, TaskObj *task)
34723461 if (prevtask == NULL ) {
34733462 return -1 ;
34743463 }
3475-
3476- if ( register_eager_task ( state , ( PyObject * ) task ) == -1 ) {
3477- Py_DECREF ( prevtask );
3478- return -1 ;
3479- }
3464+ // register the task into the linked list of tasks
3465+ // if the task completes eagerly (without suspending) then it will unregister itself
3466+ // in future_schedule_callbacks when done, otherwise
3467+ // it will continue as a regular (non-eager) asyncio task
3468+ register_task ( task );
34803469
34813470 if (PyContext_Enter (task -> task_context ) == -1 ) {
34823471 Py_DECREF (prevtask );
@@ -3506,17 +3495,11 @@ task_eager_start(asyncio_state *state, TaskObj *task)
35063495 Py_DECREF (curtask );
35073496 }
35083497
3509- if (unregister_eager_task (state , (PyObject * )task ) == -1 ) {
3510- retval = -1 ;
3511- }
3512-
35133498 if (PyContext_Exit (task -> task_context ) == -1 ) {
35143499 retval = -1 ;
35153500 }
35163501
3517- if (task -> task_state == STATE_PENDING ) {
3518- register_task (task );
3519- } else {
3502+ if (task -> task_state != STATE_PENDING ) {
35203503 // This seems to really help performance on pyperformance benchmarks
35213504 clear_task_coro (task );
35223505 }
@@ -3735,9 +3718,18 @@ _asyncio__register_eager_task_impl(PyObject *module, PyObject *task)
37353718/*[clinic end generated code: output=dfe1d45367c73f1a input=237f684683398c51]*/
37363719{
37373720 asyncio_state * state = get_asyncio_state (module );
3738- if (register_eager_task (state , task ) < 0 ) {
3721+
3722+ if (Task_Check (state , task )) {
3723+ // task is an asyncio.Task instance or subclass, use efficient
3724+ // linked-list implementation.
3725+ register_task ((TaskObj * )task );
3726+ Py_RETURN_NONE ;
3727+ }
3728+
3729+ if (PySet_Add (state -> non_asyncio_eager_tasks , task ) < 0 ) {
37393730 return NULL ;
37403731 }
3732+
37413733 Py_RETURN_NONE ;
37423734}
37433735
@@ -3785,9 +3777,17 @@ _asyncio__unregister_eager_task_impl(PyObject *module, PyObject *task)
37853777/*[clinic end generated code: output=a426922bd07f23d1 input=9d07401ef14ee048]*/
37863778{
37873779 asyncio_state * state = get_asyncio_state (module );
3788- if (unregister_eager_task (state , task ) < 0 ) {
3780+ if (Task_Check (state , task )) {
3781+ // task is an asyncio.Task instance or subclass, use efficient
3782+ // linked-list implementation.
3783+ unregister_task ((TaskObj * )task );
3784+ Py_RETURN_NONE ;
3785+ }
3786+
3787+ if (PySet_Discard (state -> non_asyncio_eager_tasks , task ) < 0 ) {
37893788 return NULL ;
37903789 }
3790+
37913791 Py_RETURN_NONE ;
37923792}
37933793
@@ -4041,7 +4041,7 @@ _asyncio_all_tasks_impl(PyObject *module, PyObject *loop)
40414041 Py_DECREF (loop );
40424042 return NULL ;
40434043 }
4044- if (PyList_Extend (tasks , state -> eager_tasks ) < 0 ) {
4044+ if (PyList_Extend (tasks , state -> non_asyncio_eager_tasks ) < 0 ) {
40454045 Py_DECREF (tasks );
40464046 Py_DECREF (loop );
40474047 return NULL ;
@@ -4179,7 +4179,7 @@ module_traverse(PyObject *mod, visitproc visit, void *arg)
41794179 Py_VISIT (state -> asyncio_CancelledError );
41804180
41814181 Py_VISIT (state -> non_asyncio_tasks );
4182- Py_VISIT (state -> eager_tasks );
4182+ Py_VISIT (state -> non_asyncio_eager_tasks );
41834183 Py_VISIT (state -> iscoroutine_typecache );
41844184
41854185 Py_VISIT (state -> context_kwname );
@@ -4209,7 +4209,7 @@ module_clear(PyObject *mod)
42094209 Py_CLEAR (state -> asyncio_CancelledError );
42104210
42114211 Py_CLEAR (state -> non_asyncio_tasks );
4212- Py_CLEAR (state -> eager_tasks );
4212+ Py_CLEAR (state -> non_asyncio_eager_tasks );
42134213 Py_CLEAR (state -> iscoroutine_typecache );
42144214
42154215 Py_CLEAR (state -> context_kwname );
@@ -4292,8 +4292,8 @@ module_init(asyncio_state *state)
42924292 goto fail ;
42934293 }
42944294
4295- state -> eager_tasks = PySet_New (NULL );
4296- if (state -> eager_tasks == NULL ) {
4295+ state -> non_asyncio_eager_tasks = PySet_New (NULL );
4296+ if (state -> non_asyncio_eager_tasks == NULL ) {
42974297 goto fail ;
42984298 }
42994299
@@ -4363,14 +4363,6 @@ module_exec(PyObject *mod)
43634363 return -1 ;
43644364 }
43654365
4366- if (PyModule_AddObjectRef (mod , "_scheduled_tasks" , state -> non_asyncio_tasks ) < 0 ) {
4367- return -1 ;
4368- }
4369-
4370- if (PyModule_AddObjectRef (mod , "_eager_tasks" , state -> eager_tasks ) < 0 ) {
4371- return -1 ;
4372- }
4373-
43744366 return 0 ;
43754367}
43764368
0 commit comments