summaryrefslogtreecommitdiff
path: root/Lib/asyncio/events.py
diff options
context:
space:
mode:
authorYury Selivanov <yury@magic.io>2016-11-04 14:29:28 -0400
committerYury Selivanov <yury@magic.io>2016-11-04 14:29:28 -0400
commit3fa4acee3c6cc15bedbcb3b91b7a603bd8a53ac8 (patch)
tree6cd693347f239f244b8e5bdc808543a6ffedd043 /Lib/asyncio/events.py
parent897d61aeada8a739bf3b5c435df88f1c3c8ba60c (diff)
downloadcpython-3fa4acee3c6cc15bedbcb3b91b7a603bd8a53ac8.tar.gz
Issue #28613: Fix get_event_loop() to return the current loop
when called from coroutines or callbacks.
Diffstat (limited to 'Lib/asyncio/events.py')
-rw-r--r--Lib/asyncio/events.py36
1 files changed, 35 insertions, 1 deletions
diff --git a/Lib/asyncio/events.py b/Lib/asyncio/events.py
index b89b4b205a..8575e2c1c4 100644
--- a/Lib/asyncio/events.py
+++ b/Lib/asyncio/events.py
@@ -607,6 +607,30 @@ _event_loop_policy = None
_lock = threading.Lock()
+# A TLS for the running event loop, used by _get_running_loop.
+class _RunningLoop(threading.local):
+ _loop = None
+_running_loop = _RunningLoop()
+
+
+def _get_running_loop():
+ """Return the running event loop or None.
+
+ This is a low-level function intended to be used by event loops.
+ This function is thread-specific.
+ """
+ return _running_loop._loop
+
+
+def _set_running_loop(loop):
+ """Set the running event loop.
+
+ This is a low-level function intended to be used by event loops.
+ This function is thread-specific.
+ """
+ _running_loop._loop = loop
+
+
def _init_event_loop_policy():
global _event_loop_policy
with _lock:
@@ -632,7 +656,17 @@ def set_event_loop_policy(policy):
def get_event_loop():
- """Equivalent to calling get_event_loop_policy().get_event_loop()."""
+ """Return an asyncio event loop.
+
+ When called from a coroutine or a callback (e.g. scheduled with call_soon
+ or similar API), this function will always return the running event loop.
+
+ If there is no running event loop set, the function will return
+ the result of `get_event_loop_policy().get_event_loop()` call.
+ """
+ current_loop = _get_running_loop()
+ if current_loop is not None:
+ return current_loop
return get_event_loop_policy().get_event_loop()