bpo-31787: Prevent refleaks when calling init() more than once (G… · python/cpython@d019bc8 (original) (raw)
`@@ -458,13 +458,27 @@ future_schedule_callbacks(FutureObj *fut)
`
458
458
`return 0;
`
459
459
`}
`
460
460
``
``
461
+
461
462
`static int
`
462
463
`future_init(FutureObj *fut, PyObject *loop)
`
463
464
`{
`
464
465
`PyObject *res;
`
465
466
`int is_true;
`
466
467
`_Py_IDENTIFIER(get_debug);
`
467
468
``
``
469
`+
// Same to FutureObj_clear() but not clearing fut->dict
`
``
470
`+
Py_CLEAR(fut->fut_loop);
`
``
471
`+
Py_CLEAR(fut->fut_callback0);
`
``
472
`+
Py_CLEAR(fut->fut_context0);
`
``
473
`+
Py_CLEAR(fut->fut_callbacks);
`
``
474
`+
Py_CLEAR(fut->fut_result);
`
``
475
`+
Py_CLEAR(fut->fut_exception);
`
``
476
`+
Py_CLEAR(fut->fut_source_tb);
`
``
477
+
``
478
`+
fut->fut_state = STATE_PENDING;
`
``
479
`+
fut->fut_log_tb = 0;
`
``
480
`+
fut->fut_blocking = 0;
`
``
481
+
468
482
`if (loop == Py_None) {
`
469
483
`loop = get_event_loop();
`
470
484
`if (loop == NULL) {
`
`@@ -474,7 +488,7 @@ future_init(FutureObj *fut, PyObject *loop)
`
474
488
`else {
`
475
489
`Py_INCREF(loop);
`
476
490
` }
`
477
``
`-
Py_XSETREF(fut->fut_loop, loop);
`
``
491
`+
fut->fut_loop = loop;
`
478
492
``
479
493
`res = _PyObject_CallMethodId(fut->fut_loop, &PyId_get_debug, NULL);
`
480
494
`if (res == NULL) {
`
`@@ -486,16 +500,12 @@ future_init(FutureObj *fut, PyObject *loop)
`
486
500
`return -1;
`
487
501
` }
`
488
502
`if (is_true) {
`
489
``
`-
Py_XSETREF(fut->fut_source_tb, _PyObject_CallNoArg(traceback_extract_stack));
`
``
503
`+
fut->fut_source_tb = _PyObject_CallNoArg(traceback_extract_stack);
`
490
504
`if (fut->fut_source_tb == NULL) {
`
491
505
`return -1;
`
492
506
` }
`
493
507
` }
`
494
508
``
495
``
`-
fut->fut_callback0 = NULL;
`
496
``
`-
fut->fut_context0 = NULL;
`
497
``
`-
fut->fut_callbacks = NULL;
`
498
``
-
499
509
`return 0;
`
500
510
`}
`
501
511
``
`@@ -1938,16 +1948,16 @@ _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop)
`
1938
1948
`return -1;
`
1939
1949
` }
`
1940
1950
``
1941
``
`-
self->task_context = PyContext_CopyCurrent();
`
``
1951
`+
Py_XSETREF(self->task_context, PyContext_CopyCurrent());
`
1942
1952
`if (self->task_context == NULL) {
`
1943
1953
`return -1;
`
1944
1954
` }
`
1945
1955
``
1946
``
`-
self->task_fut_waiter = NULL;
`
``
1956
`+
Py_CLEAR(self->task_fut_waiter);
`
1947
1957
`self->task_must_cancel = 0;
`
1948
1958
`self->task_log_destroy_pending = 1;
`
1949
1959
`Py_INCREF(coro);
`
1950
``
`-
self->task_coro = coro;
`
``
1960
`+
Py_XSETREF(self->task_coro, coro);
`
1951
1961
``
1952
1962
`if (task_call_step_soon(self, NULL)) {
`
1953
1963
`return -1;
`