@@ -549,30 +549,28 @@ future_init(FutureObj *fut, PyObject *loop)
549549}
550550
551551static int
552- future_awaited_by_add (asyncio_state * state , PyObject * fut , PyObject * thing )
552+ future_awaited_by_add (asyncio_state * state , FutureObj * fut , PyObject * thing )
553553{
554- if (!TaskOrFuture_Check (state , fut ) || !TaskOrFuture_Check (state , thing )) {
555- // We only want to support native asyncio Futures.
556- // For further insight see the comment in the Python
557- // implementation of "future_add_to_awaited_by()".
558- return 0 ;
559- }
560-
561- FutureObj * _fut = (FutureObj * )fut ;
554+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED (fut );
555+ // We only want to support native asyncio Futures.
556+ // For further insight see the comment in the Python
557+ // implementation of "future_add_to_awaited_by()".
558+ assert (TaskOrFuture_Check (state , fut ));
559+ assert (TaskOrFuture_Check (state , thing ));
562560
563561 /* Most futures/task are only awaited by one entity, so we want
564562 to avoid always creating a set for `fut_awaited_by`.
565563 */
566- if (_fut -> fut_awaited_by == NULL ) {
567- assert (!_fut -> fut_awaited_by_is_set );
564+ if (fut -> fut_awaited_by == NULL ) {
565+ assert (!fut -> fut_awaited_by_is_set );
568566 Py_INCREF (thing );
569- _fut -> fut_awaited_by = thing ;
567+ fut -> fut_awaited_by = thing ;
570568 return 0 ;
571569 }
572570
573- if (_fut -> fut_awaited_by_is_set ) {
574- assert (PySet_CheckExact (_fut -> fut_awaited_by ));
575- return PySet_Add (_fut -> fut_awaited_by , thing );
571+ if (fut -> fut_awaited_by_is_set ) {
572+ assert (PySet_CheckExact (fut -> fut_awaited_by ));
573+ return PySet_Add (fut -> fut_awaited_by , thing );
576574 }
577575
578576 PyObject * set = PySet_New (NULL );
@@ -583,40 +581,38 @@ future_awaited_by_add(asyncio_state *state, PyObject *fut, PyObject *thing)
583581 Py_DECREF (set );
584582 return -1 ;
585583 }
586- if (PySet_Add (set , _fut -> fut_awaited_by )) {
584+ if (PySet_Add (set , fut -> fut_awaited_by )) {
587585 Py_DECREF (set );
588586 return -1 ;
589587 }
590- Py_SETREF (_fut -> fut_awaited_by , set );
591- _fut -> fut_awaited_by_is_set = 1 ;
588+ Py_SETREF (fut -> fut_awaited_by , set );
589+ fut -> fut_awaited_by_is_set = 1 ;
592590 return 0 ;
593591}
594592
595593static int
596- future_awaited_by_discard (asyncio_state * state , PyObject * fut , PyObject * thing )
594+ future_awaited_by_discard (asyncio_state * state , FutureObj * fut , PyObject * thing )
597595{
598- if (!TaskOrFuture_Check (state , fut ) || !TaskOrFuture_Check (state , thing )) {
599- // We only want to support native asyncio Futures.
600- // For further insight see the comment in the Python
601- // implementation of "future_add_to_awaited_by()".
602- return 0 ;
603- }
604-
605- FutureObj * _fut = (FutureObj * )fut ;
596+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED (fut );
597+ // We only want to support native asyncio Futures.
598+ // For further insight see the comment in the Python
599+ // implementation of "future_add_to_awaited_by()".
600+ assert (TaskOrFuture_Check (state , fut ));
601+ assert (TaskOrFuture_Check (state , thing ));
606602
607603 /* Following the semantics of 'set.discard()' here in not
608604 raising an error if `thing` isn't in the `awaited_by` "set".
609605 */
610- if (_fut -> fut_awaited_by == NULL ) {
606+ if (fut -> fut_awaited_by == NULL ) {
611607 return 0 ;
612608 }
613- if (_fut -> fut_awaited_by == thing ) {
614- Py_CLEAR (_fut -> fut_awaited_by );
609+ if (fut -> fut_awaited_by == thing ) {
610+ Py_CLEAR (fut -> fut_awaited_by );
615611 return 0 ;
616612 }
617- if (_fut -> fut_awaited_by_is_set ) {
618- assert (PySet_CheckExact (_fut -> fut_awaited_by ));
619- int err = PySet_Discard (_fut -> fut_awaited_by , thing );
613+ if (fut -> fut_awaited_by_is_set ) {
614+ assert (PySet_CheckExact (fut -> fut_awaited_by ));
615+ int err = PySet_Discard (fut -> fut_awaited_by , thing );
620616 if (err < 0 ) {
621617 return -1 ;
622618 } else {
@@ -626,36 +622,6 @@ future_awaited_by_discard(asyncio_state *state, PyObject *fut, PyObject *thing)
626622 return 0 ;
627623}
628624
629- /*[clinic input]
630- @critical_section
631- @getter
632- _asyncio.Future._asyncio_awaited_by
633- [clinic start generated code]*/
634-
635- static PyObject *
636- _asyncio_Future__asyncio_awaited_by_get_impl (FutureObj * self )
637- /*[clinic end generated code: output=932af76d385d2e2a input=64c1783df2d44d2b]*/
638- {
639- /* Implementation of a Python getter. */
640- if (self -> fut_awaited_by == NULL ) {
641- Py_RETURN_NONE ;
642- }
643- if (self -> fut_awaited_by_is_set ) {
644- /* Already a set, just wrap it into a frozen set and return. */
645- assert (PySet_CheckExact (self -> fut_awaited_by ));
646- return PyFrozenSet_New (self -> fut_awaited_by );
647- }
648-
649- PyObject * set = PyFrozenSet_New (NULL );
650- if (set == NULL ) {
651- return NULL ;
652- }
653- if (PySet_Add (set , self -> fut_awaited_by )) {
654- Py_DECREF (set );
655- return NULL ;
656- }
657- return set ;
658- }
659625
660626static PyObject *
661627future_set_result (asyncio_state * state , FutureObj * fut , PyObject * res )
@@ -1362,6 +1328,38 @@ _asyncio_Future_get_loop_impl(FutureObj *self, PyTypeObject *cls)
13621328 return Py_NewRef (self -> fut_loop );
13631329}
13641330
1331+ /*[clinic input]
1332+ @critical_section
1333+ @getter
1334+ _asyncio.Future._asyncio_awaited_by
1335+ [clinic start generated code]*/
1336+
1337+ static PyObject *
1338+ _asyncio_Future__asyncio_awaited_by_get_impl (FutureObj * self )
1339+ /*[clinic end generated code: output=932af76d385d2e2a input=64c1783df2d44d2b]*/
1340+ {
1341+ /* Implementation of a Python getter. */
1342+ if (self -> fut_awaited_by == NULL ) {
1343+ Py_RETURN_NONE ;
1344+ }
1345+ if (self -> fut_awaited_by_is_set ) {
1346+ /* Already a set, just wrap it into a frozen set and return. */
1347+ assert (PySet_CheckExact (self -> fut_awaited_by ));
1348+ return PyFrozenSet_New (self -> fut_awaited_by );
1349+ }
1350+
1351+ PyObject * set = PyFrozenSet_New (NULL );
1352+ if (set == NULL ) {
1353+ return NULL ;
1354+ }
1355+ if (PySet_Add (set , self -> fut_awaited_by )) {
1356+ Py_DECREF (set );
1357+ return NULL ;
1358+ }
1359+ return set ;
1360+ }
1361+
1362+
13651363/*[clinic input]
13661364@critical_section
13671365@getter
@@ -3296,8 +3294,11 @@ task_step_handle_result_impl(asyncio_state *state, TaskObj *task, PyObject *resu
32963294 if (!fut -> fut_blocking ) {
32973295 goto yield_insteadof_yf ;
32983296 }
3299-
3300- if (future_awaited_by_add (state , result , (PyObject * )task )) {
3297+ int res ;
3298+ Py_BEGIN_CRITICAL_SECTION (result );
3299+ res = future_awaited_by_add (state , (FutureObj * )result , (PyObject * )task );
3300+ Py_END_CRITICAL_SECTION ();
3301+ if (res ) {
33013302 goto fail ;
33023303 }
33033304
@@ -3390,8 +3391,14 @@ task_step_handle_result_impl(asyncio_state *state, TaskObj *task, PyObject *resu
33903391 goto yield_insteadof_yf ;
33913392 }
33923393
3393- if (future_awaited_by_add (state , result , (PyObject * )task )) {
3394- goto fail ;
3394+ if (TaskOrFuture_Check (state , result )) {
3395+ int res ;
3396+ Py_BEGIN_CRITICAL_SECTION (result );
3397+ res = future_awaited_by_add (state , (FutureObj * )result , (PyObject * )task );
3398+ Py_END_CRITICAL_SECTION ();
3399+ if (res ) {
3400+ goto fail ;
3401+ }
33953402 }
33963403
33973404 /* result._asyncio_future_blocking = False */
@@ -3606,8 +3613,14 @@ task_wakeup_lock_held(TaskObj *task, PyObject *o)
36063613
36073614 asyncio_state * state = get_asyncio_state_by_def ((PyObject * )task );
36083615
3609- if (future_awaited_by_discard (state , o , (PyObject * )task )) {
3610- return NULL ;
3616+ if (TaskOrFuture_Check (state , o )) {
3617+ int res ;
3618+ Py_BEGIN_CRITICAL_SECTION (o );
3619+ res = future_awaited_by_discard (state , (FutureObj * )o , (PyObject * )task );
3620+ Py_END_CRITICAL_SECTION ();
3621+ if (res ) {
3622+ return NULL ;
3623+ }
36113624 }
36123625
36133626 if (Future_CheckExact (state , o ) || Task_CheckExact (state , o )) {
@@ -4110,8 +4123,14 @@ _asyncio_future_add_to_awaited_by_impl(PyObject *module, PyObject *fut,
41104123/*[clinic end generated code: output=0ab9a1a63389e4df input=06e6eaac51f532b9]*/
41114124{
41124125 asyncio_state * state = get_asyncio_state (module );
4113- if (future_awaited_by_add (state , fut , waiter )) {
4114- return NULL ;
4126+ if (TaskOrFuture_Check (state , fut ) && TaskOrFuture_Check (state , waiter )) {
4127+ int res ;
4128+ Py_BEGIN_CRITICAL_SECTION (fut );
4129+ res = future_awaited_by_add (state , (FutureObj * )fut , waiter );
4130+ Py_END_CRITICAL_SECTION ();
4131+ if (res ) {
4132+ return NULL ;
4133+ }
41154134 }
41164135 Py_RETURN_NONE ;
41174136}
@@ -4131,8 +4150,14 @@ _asyncio_future_discard_from_awaited_by_impl(PyObject *module, PyObject *fut,
41314150/*[clinic end generated code: output=a03b0b4323b779de input=3833f7639e88e483]*/
41324151{
41334152 asyncio_state * state = get_asyncio_state (module );
4134- if (future_awaited_by_discard (state , fut , waiter )) {
4135- return NULL ;
4153+ if (TaskOrFuture_Check (state , fut ) && TaskOrFuture_Check (state , waiter )) {
4154+ int res ;
4155+ Py_BEGIN_CRITICAL_SECTION (fut );
4156+ res = future_awaited_by_add (state , (FutureObj * )fut , waiter );
4157+ Py_END_CRITICAL_SECTION ();
4158+ if (res ) {
4159+ return NULL ;
4160+ }
41364161 }
41374162 Py_RETURN_NONE ;
41384163}
0 commit comments