@@ -143,8 +143,9 @@ typedef struct {
143
143
inherit from native asyncio.Task */
144
144
PyObject * non_asyncio_tasks ;
145
145
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 ;
148
149
149
150
/* An isinstance type cache for the 'is_coroutine()' function. */
150
151
PyObject * iscoroutine_typecache ;
@@ -2180,12 +2181,6 @@ register_task(TaskObj *task)
2180
2181
llist_insert_tail (head , & task -> task_node );
2181
2182
}
2182
2183
2183
- static int
2184
- register_eager_task (asyncio_state * state , PyObject * task )
2185
- {
2186
- return PySet_Add (state -> eager_tasks , task );
2187
- }
2188
-
2189
2184
static inline void
2190
2185
unregister_task_safe (TaskObj * task )
2191
2186
{
@@ -2219,12 +2214,6 @@ unregister_task(TaskObj *task)
2219
2214
#endif
2220
2215
}
2221
2216
2222
- static int
2223
- unregister_eager_task (asyncio_state * state , PyObject * task )
2224
- {
2225
- return PySet_Discard (state -> eager_tasks , task );
2226
- }
2227
-
2228
2217
static int
2229
2218
enter_task (PyObject * loop , PyObject * task )
2230
2219
{
@@ -3472,11 +3461,11 @@ task_eager_start(asyncio_state *state, TaskObj *task)
3472
3461
if (prevtask == NULL ) {
3473
3462
return -1 ;
3474
3463
}
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 );
3480
3469
3481
3470
if (PyContext_Enter (task -> task_context ) == -1 ) {
3482
3471
Py_DECREF (prevtask );
@@ -3506,17 +3495,11 @@ task_eager_start(asyncio_state *state, TaskObj *task)
3506
3495
Py_DECREF (curtask );
3507
3496
}
3508
3497
3509
- if (unregister_eager_task (state , (PyObject * )task ) == -1 ) {
3510
- retval = -1 ;
3511
- }
3512
-
3513
3498
if (PyContext_Exit (task -> task_context ) == -1 ) {
3514
3499
retval = -1 ;
3515
3500
}
3516
3501
3517
- if (task -> task_state == STATE_PENDING ) {
3518
- register_task (task );
3519
- } else {
3502
+ if (task -> task_state != STATE_PENDING ) {
3520
3503
// This seems to really help performance on pyperformance benchmarks
3521
3504
clear_task_coro (task );
3522
3505
}
@@ -3735,9 +3718,18 @@ _asyncio__register_eager_task_impl(PyObject *module, PyObject *task)
3735
3718
/*[clinic end generated code: output=dfe1d45367c73f1a input=237f684683398c51]*/
3736
3719
{
3737
3720
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 ) {
3739
3730
return NULL ;
3740
3731
}
3732
+
3741
3733
Py_RETURN_NONE ;
3742
3734
}
3743
3735
@@ -3785,9 +3777,17 @@ _asyncio__unregister_eager_task_impl(PyObject *module, PyObject *task)
3785
3777
/*[clinic end generated code: output=a426922bd07f23d1 input=9d07401ef14ee048]*/
3786
3778
{
3787
3779
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 ) {
3789
3788
return NULL ;
3790
3789
}
3790
+
3791
3791
Py_RETURN_NONE ;
3792
3792
}
3793
3793
@@ -4041,7 +4041,7 @@ _asyncio_all_tasks_impl(PyObject *module, PyObject *loop)
4041
4041
Py_DECREF (loop );
4042
4042
return NULL ;
4043
4043
}
4044
- if (PyList_Extend (tasks , state -> eager_tasks ) < 0 ) {
4044
+ if (PyList_Extend (tasks , state -> non_asyncio_eager_tasks ) < 0 ) {
4045
4045
Py_DECREF (tasks );
4046
4046
Py_DECREF (loop );
4047
4047
return NULL ;
@@ -4179,7 +4179,7 @@ module_traverse(PyObject *mod, visitproc visit, void *arg)
4179
4179
Py_VISIT (state -> asyncio_CancelledError );
4180
4180
4181
4181
Py_VISIT (state -> non_asyncio_tasks );
4182
- Py_VISIT (state -> eager_tasks );
4182
+ Py_VISIT (state -> non_asyncio_eager_tasks );
4183
4183
Py_VISIT (state -> iscoroutine_typecache );
4184
4184
4185
4185
Py_VISIT (state -> context_kwname );
@@ -4209,7 +4209,7 @@ module_clear(PyObject *mod)
4209
4209
Py_CLEAR (state -> asyncio_CancelledError );
4210
4210
4211
4211
Py_CLEAR (state -> non_asyncio_tasks );
4212
- Py_CLEAR (state -> eager_tasks );
4212
+ Py_CLEAR (state -> non_asyncio_eager_tasks );
4213
4213
Py_CLEAR (state -> iscoroutine_typecache );
4214
4214
4215
4215
Py_CLEAR (state -> context_kwname );
@@ -4292,8 +4292,8 @@ module_init(asyncio_state *state)
4292
4292
goto fail ;
4293
4293
}
4294
4294
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 ) {
4297
4297
goto fail ;
4298
4298
}
4299
4299
@@ -4363,14 +4363,6 @@ module_exec(PyObject *mod)
4363
4363
return -1 ;
4364
4364
}
4365
4365
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
-
4374
4366
return 0 ;
4375
4367
}
4376
4368
0 commit comments