Skip to content

Commit

Permalink
gh-105987: Fix reference counting issue in `_asyncio._swap_current_ta…
Browse files Browse the repository at this point in the history
…sk` (#105989)
  • Loading branch information
chgnrdv authored Jun 24, 2023
1 parent 4849a80 commit d2cbb6e
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 4 deletions.
19 changes: 19 additions & 0 deletions Lib/test/test_asyncio/test_eager_task_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
from unittest import mock
from asyncio import tasks
from test.test_asyncio import utils as test_utils
import test.support
from test.support.script_helper import assert_python_ok

MOCK_ANY = mock.ANY

Expand Down Expand Up @@ -222,6 +224,23 @@ class PyEagerTaskFactoryLoopTests(EagerTaskFactoryLoopTests, test_utils.TestCase
class CEagerTaskFactoryLoopTests(EagerTaskFactoryLoopTests, test_utils.TestCase):
Task = getattr(tasks, '_CTask', None)

def test_issue105987(self):
code = """if 1:
from _asyncio import _swap_current_task
class DummyTask:
pass
class DummyLoop:
pass
l = DummyLoop()
_swap_current_task(l, DummyTask())
t = _swap_current_task(l, None)
"""

_, out, err = assert_python_ok("-c", code)
self.assertFalse(err)

class AsyncTaskCounter:
def __init__(self, loop, *, task_class, eager):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix crash due to improper reference counting in :mod:`asyncio` eager task factory internal routines.
11 changes: 7 additions & 4 deletions Modules/_asynciomodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -2047,20 +2047,23 @@ swap_current_task(asyncio_state *state, PyObject *loop, PyObject *task)
}
prev_task = Py_None;
}
Py_INCREF(prev_task);

if (task == Py_None) {
if (_PyDict_DelItem_KnownHash(state->current_tasks, loop, hash) == -1) {
return NULL;
goto error;
}
} else {
if (_PyDict_SetItem_KnownHash(state->current_tasks, loop, task, hash) == -1) {
return NULL;
goto error;
}
}

Py_INCREF(prev_task);

return prev_task;

error:
Py_DECREF(prev_task);
return NULL;
}

/* ----- Task */
Expand Down

0 comments on commit d2cbb6e

Please sign in to comment.