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;

`