Skip to content

Commit e22655b

Browse files
committed
keep python and C current task in sync
1 parent 85ad18e commit e22655b

File tree

1 file changed

+21
-6
lines changed

1 file changed

+21
-6
lines changed

Lib/asyncio/tasks.py

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ def current_task(loop=None):
3838
"""Return a currently executed task."""
3939
if loop is None:
4040
loop = events.get_running_loop()
41+
42+
# If we have a C implementation, prefer it
43+
if current_task is not _py_current_task:
44+
return _c_current_task(loop)
45+
46+
# Fall back to Python state
4147
return _current_tasks.get(loop)
4248

4349

@@ -273,15 +279,12 @@ def __step(self, exc=None):
273279
self._must_cancel = False
274280
self._fut_waiter = None
275281

276-
prev_task = _py_swap_current_task(self._loop, self)
282+
_py_enter_task(self._loop, self)
277283
try:
278284
self.__step_run_and_handle_result(exc)
279285
finally:
280-
try:
281-
curtask = _py_swap_current_task(self._loop, prev_task)
282-
assert curtask is self
283-
finally:
284-
self = None # Needed to break cycles when an exception occurs.
286+
_py_leave_task(self._loop, self)
287+
self = None # Needed to break cycles when an exception occurs.
285288

286289
def __step_run_and_handle_result(self, exc):
287290
coro = self._coro
@@ -1069,6 +1072,9 @@ def factory(loop, coro, *, eager_start=True, **kwargs):
10691072
# all running event loops. {EventLoop: Task}
10701073
_current_tasks = {}
10711074

1075+
# Initialize C function references to Python implementations
1076+
_c_current_task = None
1077+
10721078

10731079
def _register_task(task):
10741080
"""Register an asyncio Task scheduled to run on an event loop."""
@@ -1086,6 +1092,9 @@ def _enter_task(loop, task):
10861092
raise RuntimeError(f"Cannot enter into task {task!r} while another "
10871093
f"task {current_task!r} is being executed.")
10881094
_current_tasks[loop] = task
1095+
if _c_swap_current_task is not _py_swap_current_task:
1096+
# keep the C task state in sync
1097+
_c_swap_current_task(loop, task)
10891098

10901099

10911100
def _leave_task(loop, task):
@@ -1094,6 +1103,9 @@ def _leave_task(loop, task):
10941103
raise RuntimeError(f"Leaving task {task!r} does not match "
10951104
f"the current task {current_task!r}.")
10961105
del _current_tasks[loop]
1106+
if _c_swap_current_task is not _py_swap_current_task:
1107+
# keep the C task state in sync
1108+
_c_swap_current_task(loop, None)
10971109

10981110

10991111
def _swap_current_task(loop, task):
@@ -1128,6 +1140,9 @@ def _unregister_eager_task(task):
11281140
_py_swap_current_task = _swap_current_task
11291141
_py_all_tasks = all_tasks
11301142

1143+
# Initially point C functions to Python implementations
1144+
_c_current_task = current_task
1145+
11311146
try:
11321147
from _asyncio import (_register_task, _register_eager_task,
11331148
_unregister_task, _unregister_eager_task,

0 commit comments

Comments
 (0)