@@ -97,10 +97,6 @@ typedef struct {
9797 PyObject * asyncio_mod ;
9898 PyObject * context_kwname ;
9999
100- /* Dictionary containing tasks that are currently active in
101- all running event loops. {EventLoop: Task} */
102- PyObject * current_tasks ;
103-
104100 /* WeakSet containing scheduled 3rd party tasks which don't
105101 inherit from native asyncio.Task */
106102 PyObject * non_asyncio_tasks ;
@@ -1926,11 +1922,10 @@ static int
19261922enter_task (asyncio_state * state , PyObject * loop , PyObject * task )
19271923{
19281924 PyObject * item ;
1929- int res = PyDict_SetDefaultRef (state -> current_tasks , loop , task , & item );
1930- if (res < 0 ) {
1925+ if (PyObject_GetOptionalAttr (loop , & _Py_ID (_current_task ), & item ) < 0 ) {
19311926 return -1 ;
19321927 }
1933- else if (res == 1 ) {
1928+ if (item != NULL && item != Py_None ) {
19341929 PyErr_Format (
19351930 PyExc_RuntimeError ,
19361931 "Cannot enter into task %R while another " \
@@ -1939,84 +1934,63 @@ enter_task(asyncio_state *state, PyObject *loop, PyObject *task)
19391934 Py_DECREF (item );
19401935 return -1 ;
19411936 }
1942- Py_DECREF (item );
1943- return 0 ;
1944- }
1945-
1946- static int
1947- err_leave_task (PyObject * item , PyObject * task )
1948- {
1949- PyErr_Format (
1950- PyExc_RuntimeError ,
1951- "Leaving task %R does not match the current task %R." ,
1952- task , item );
1953- return -1 ;
1954- }
19551937
1956- static int
1957- leave_task_predicate (PyObject * item , void * task )
1958- {
1959- if (item != task ) {
1960- return err_leave_task (item , (PyObject * )task );
1938+ if (PyObject_SetAttr (loop , & _Py_ID (_current_task ), task ) < 0 ) {
1939+ return -1 ;
19611940 }
1962- return 1 ;
1941+ return 0 ;
19631942}
19641943
19651944static int
19661945leave_task (asyncio_state * state , PyObject * loop , PyObject * task )
1967- /*[clinic end generated code: output=0ebf6db4b858fb41 input=51296a46313d1ad8]*/
19681946{
1969- int res = _PyDict_DelItemIf (state -> current_tasks , loop ,
1970- leave_task_predicate , task );
1971- if (res == 0 ) {
1972- // task was not found
1973- return err_leave_task (Py_None , task );
1947+ PyObject * item ;
1948+ if (PyObject_GetOptionalAttr (loop , & _Py_ID (_current_task ), & item ) < 0 ) {
1949+ return -1 ;
19741950 }
1975- return res ;
1976- }
19771951
1978- static PyObject *
1979- swap_current_task_lock_held (PyDictObject * current_tasks , PyObject * loop ,
1980- Py_hash_t hash , PyObject * task )
1981- {
1982- PyObject * prev_task ;
1983- if (_PyDict_GetItemRef_KnownHash_LockHeld (current_tasks , loop , hash , & prev_task ) < 0 ) {
1984- return NULL ;
1952+ if (item == NULL || item == Py_None ) {
1953+ // current task is not set
1954+ PyErr_Format (PyExc_RuntimeError ,
1955+ "Leaving task %R does not match the current task %R." ,
1956+ task , Py_None );
1957+ return -1 ;
19851958 }
1986- if (_PyDict_SetItem_KnownHash_LockHeld (current_tasks , loop , task , hash ) < 0 ) {
1987- Py_XDECREF (prev_task );
1988- return NULL ;
1959+
1960+ if (item != task ) {
1961+ // different task
1962+ PyErr_Format (PyExc_RuntimeError ,
1963+ "Leaving task %R does not match the current task %R." ,
1964+ task , item );
1965+ Py_DECREF (item );
1966+ return -1 ;
19891967 }
1990- if (prev_task == NULL ) {
1991- Py_RETURN_NONE ;
1968+ Py_DECREF (item );
1969+
1970+ if (PyObject_SetAttr (loop , & _Py_ID (_current_task ), Py_None ) < 0 ) {
1971+ return -1 ;
19921972 }
1993- return prev_task ;
1973+ return 0 ;
19941974}
19951975
1976+
19961977static PyObject *
19971978swap_current_task (asyncio_state * state , PyObject * loop , PyObject * task )
19981979{
19991980 PyObject * prev_task ;
20001981
2001- if (task == Py_None ) {
2002- if (PyDict_Pop (state -> current_tasks , loop , & prev_task ) < 0 ) {
2003- return NULL ;
2004- }
2005- if (prev_task == NULL ) {
2006- Py_RETURN_NONE ;
2007- }
2008- return prev_task ;
1982+ if (PyObject_GetOptionalAttr (loop , & _Py_ID (_current_task ), & prev_task ) < 0 ) {
1983+ return NULL ;
20091984 }
20101985
2011- Py_hash_t hash = PyObject_Hash ( loop );
2012- if ( hash == -1 ) {
1986+ if ( PyObject_SetAttr ( loop , & _Py_ID ( _current_task ), task ) < 0 ) {
1987+ Py_XDECREF ( prev_task );
20131988 return NULL ;
20141989 }
20151990
2016- PyDictObject * current_tasks = (PyDictObject * )state -> current_tasks ;
2017- Py_BEGIN_CRITICAL_SECTION (current_tasks );
2018- prev_task = swap_current_task_lock_held (current_tasks , loop , hash , task );
2019- Py_END_CRITICAL_SECTION ();
1991+ if (prev_task == NULL ) {
1992+ Py_RETURN_NONE ;
1993+ }
20201994 return prev_task ;
20211995}
20221996
@@ -3503,9 +3477,6 @@ static PyObject *
35033477_asyncio_current_task_impl (PyObject * module , PyObject * loop )
35043478/*[clinic end generated code: output=fe15ac331a7f981a input=58910f61a5627112]*/
35053479{
3506- PyObject * ret ;
3507- asyncio_state * state = get_asyncio_state (module );
3508-
35093480 if (loop == Py_None ) {
35103481 loop = _asyncio_get_running_loop_impl (module );
35113482 if (loop == NULL ) {
@@ -3515,12 +3486,19 @@ _asyncio_current_task_impl(PyObject *module, PyObject *loop)
35153486 Py_INCREF (loop );
35163487 }
35173488
3518- int rc = PyDict_GetItemRef (state -> current_tasks , loop , & ret );
3489+ PyObject * item ;
3490+ if (PyObject_GetOptionalAttr (loop , & _Py_ID (_current_task ), & item ) < 0 ) {
3491+ Py_DECREF (loop );
3492+ return NULL ;
3493+ }
3494+
35193495 Py_DECREF (loop );
3520- if (rc == 0 ) {
3496+
3497+ if (item == NULL ) {
35213498 Py_RETURN_NONE ;
35223499 }
3523- return ret ;
3500+
3501+ return item ;
35243502}
35253503
35263504
@@ -3675,7 +3653,6 @@ module_traverse(PyObject *mod, visitproc visit, void *arg)
36753653
36763654 Py_VISIT (state -> non_asyncio_tasks );
36773655 Py_VISIT (state -> eager_tasks );
3678- Py_VISIT (state -> current_tasks );
36793656 Py_VISIT (state -> iscoroutine_typecache );
36803657
36813658 Py_VISIT (state -> context_kwname );
@@ -3706,7 +3683,6 @@ module_clear(PyObject *mod)
37063683
37073684 Py_CLEAR (state -> non_asyncio_tasks );
37083685 Py_CLEAR (state -> eager_tasks );
3709- Py_CLEAR (state -> current_tasks );
37103686 Py_CLEAR (state -> iscoroutine_typecache );
37113687
37123688 Py_CLEAR (state -> context_kwname );
@@ -3735,10 +3711,6 @@ module_init(asyncio_state *state)
37353711 goto fail ;
37363712 }
37373713
3738- state -> current_tasks = PyDict_New ();
3739- if (state -> current_tasks == NULL ) {
3740- goto fail ;
3741- }
37423714
37433715 state -> iscoroutine_typecache = PySet_New (NULL );
37443716 if (state -> iscoroutine_typecache == NULL ) {
@@ -3872,10 +3844,6 @@ module_exec(PyObject *mod)
38723844 return -1 ;
38733845 }
38743846
3875- if (PyModule_AddObjectRef (mod , "_current_tasks" , state -> current_tasks ) < 0 ) {
3876- return -1 ;
3877- }
3878-
38793847
38803848 return 0 ;
38813849}
0 commit comments