@@ -549,30 +549,28 @@ future_init(FutureObj *fut, PyObject *loop)
549
549
}
550
550
551
551
static 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 )
553
553
{
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 ));
562
560
563
561
/* Most futures/task are only awaited by one entity, so we want
564
562
to avoid always creating a set for `fut_awaited_by`.
565
563
*/
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 );
568
566
Py_INCREF (thing );
569
- _fut -> fut_awaited_by = thing ;
567
+ fut -> fut_awaited_by = thing ;
570
568
return 0 ;
571
569
}
572
570
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 );
576
574
}
577
575
578
576
PyObject * set = PySet_New (NULL );
@@ -583,40 +581,38 @@ future_awaited_by_add(asyncio_state *state, PyObject *fut, PyObject *thing)
583
581
Py_DECREF (set );
584
582
return -1 ;
585
583
}
586
- if (PySet_Add (set , _fut -> fut_awaited_by )) {
584
+ if (PySet_Add (set , fut -> fut_awaited_by )) {
587
585
Py_DECREF (set );
588
586
return -1 ;
589
587
}
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 ;
592
590
return 0 ;
593
591
}
594
592
595
593
static 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 )
597
595
{
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 ));
606
602
607
603
/* Following the semantics of 'set.discard()' here in not
608
604
raising an error if `thing` isn't in the `awaited_by` "set".
609
605
*/
610
- if (_fut -> fut_awaited_by == NULL ) {
606
+ if (fut -> fut_awaited_by == NULL ) {
611
607
return 0 ;
612
608
}
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 );
615
611
return 0 ;
616
612
}
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 );
620
616
if (err < 0 ) {
621
617
return -1 ;
622
618
} else {
@@ -626,36 +622,6 @@ future_awaited_by_discard(asyncio_state *state, PyObject *fut, PyObject *thing)
626
622
return 0 ;
627
623
}
628
624
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
- }
659
625
660
626
static PyObject *
661
627
future_set_result (asyncio_state * state , FutureObj * fut , PyObject * res )
@@ -1362,6 +1328,38 @@ _asyncio_Future_get_loop_impl(FutureObj *self, PyTypeObject *cls)
1362
1328
return Py_NewRef (self -> fut_loop );
1363
1329
}
1364
1330
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
+
1365
1363
/*[clinic input]
1366
1364
@critical_section
1367
1365
@getter
@@ -3298,8 +3296,11 @@ task_step_handle_result_impl(asyncio_state *state, TaskObj *task, PyObject *resu
3298
3296
if (!fut -> fut_blocking ) {
3299
3297
goto yield_insteadof_yf ;
3300
3298
}
3301
-
3302
- if (future_awaited_by_add (state , result , (PyObject * )task )) {
3299
+ int res ;
3300
+ Py_BEGIN_CRITICAL_SECTION (result );
3301
+ res = future_awaited_by_add (state , (FutureObj * )result , (PyObject * )task );
3302
+ Py_END_CRITICAL_SECTION ();
3303
+ if (res ) {
3303
3304
goto fail ;
3304
3305
}
3305
3306
@@ -3392,8 +3393,14 @@ task_step_handle_result_impl(asyncio_state *state, TaskObj *task, PyObject *resu
3392
3393
goto yield_insteadof_yf ;
3393
3394
}
3394
3395
3395
- if (future_awaited_by_add (state , result , (PyObject * )task )) {
3396
- goto fail ;
3396
+ if (TaskOrFuture_Check (state , result )) {
3397
+ int res ;
3398
+ Py_BEGIN_CRITICAL_SECTION (result );
3399
+ res = future_awaited_by_add (state , (FutureObj * )result , (PyObject * )task );
3400
+ Py_END_CRITICAL_SECTION ();
3401
+ if (res ) {
3402
+ goto fail ;
3403
+ }
3397
3404
}
3398
3405
3399
3406
/* result._asyncio_future_blocking = False */
@@ -3608,8 +3615,14 @@ task_wakeup_lock_held(TaskObj *task, PyObject *o)
3608
3615
3609
3616
asyncio_state * state = get_asyncio_state_by_def ((PyObject * )task );
3610
3617
3611
- if (future_awaited_by_discard (state , o , (PyObject * )task )) {
3612
- return NULL ;
3618
+ if (TaskOrFuture_Check (state , o )) {
3619
+ int res ;
3620
+ Py_BEGIN_CRITICAL_SECTION (o );
3621
+ res = future_awaited_by_discard (state , (FutureObj * )o , (PyObject * )task );
3622
+ Py_END_CRITICAL_SECTION ();
3623
+ if (res ) {
3624
+ return NULL ;
3625
+ }
3613
3626
}
3614
3627
3615
3628
if (Future_CheckExact (state , o ) || Task_CheckExact (state , o )) {
@@ -4112,8 +4125,14 @@ _asyncio_future_add_to_awaited_by_impl(PyObject *module, PyObject *fut,
4112
4125
/*[clinic end generated code: output=0ab9a1a63389e4df input=06e6eaac51f532b9]*/
4113
4126
{
4114
4127
asyncio_state * state = get_asyncio_state (module );
4115
- if (future_awaited_by_add (state , fut , waiter )) {
4116
- return NULL ;
4128
+ if (TaskOrFuture_Check (state , fut ) && TaskOrFuture_Check (state , waiter )) {
4129
+ int res ;
4130
+ Py_BEGIN_CRITICAL_SECTION (fut );
4131
+ res = future_awaited_by_add (state , (FutureObj * )fut , waiter );
4132
+ Py_END_CRITICAL_SECTION ();
4133
+ if (res ) {
4134
+ return NULL ;
4135
+ }
4117
4136
}
4118
4137
Py_RETURN_NONE ;
4119
4138
}
@@ -4133,8 +4152,14 @@ _asyncio_future_discard_from_awaited_by_impl(PyObject *module, PyObject *fut,
4133
4152
/*[clinic end generated code: output=a03b0b4323b779de input=3833f7639e88e483]*/
4134
4153
{
4135
4154
asyncio_state * state = get_asyncio_state (module );
4136
- if (future_awaited_by_discard (state , fut , waiter )) {
4137
- return NULL ;
4155
+ if (TaskOrFuture_Check (state , fut ) && TaskOrFuture_Check (state , waiter )) {
4156
+ int res ;
4157
+ Py_BEGIN_CRITICAL_SECTION (fut );
4158
+ res = future_awaited_by_add (state , (FutureObj * )fut , waiter );
4159
+ Py_END_CRITICAL_SECTION ();
4160
+ if (res ) {
4161
+ return NULL ;
4162
+ }
4138
4163
}
4139
4164
Py_RETURN_NONE ;
4140
4165
}
0 commit comments