bpo-41247: asyncio.set_running_loop() cache running loop holder (#21406)
The running loop holder cache variable was always set to NULL when
calling set_running_loop.
Now set_running_loop saves the newly created running loop holder in the
cache variable for faster access in get_running_loop.
diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-07-08-22-03-54.bpo-41247.PndYIk.rst b/Misc/NEWS.d/next/Core and Builtins/2020-07-08-22-03-54.bpo-41247.PndYIk.rst
new file mode 100644
index 0000000..08699b6
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2020-07-08-22-03-54.bpo-41247.PndYIk.rst
@@ -0,0 +1,2 @@
+Always cache the running loop holder when running
+``asyncio.set_running_loop``.
diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c
index 8e1cd4f..4ed2af5 100644
--- a/Modules/_asynciomodule.c
+++ b/Modules/_asynciomodule.c
@@ -289,9 +289,6 @@
static int
set_running_loop(PyObject *loop)
{
- cached_running_holder = NULL;
- cached_running_holder_tsid = 0;
-
PyObject *ts_dict = PyThreadState_GetDict(); // borrowed
if (ts_dict == NULL) {
PyErr_SetString(
@@ -312,6 +309,12 @@
}
Py_DECREF(rl);
+ cached_running_holder = (PyObject *)rl;
+
+ /* safe to assume state is not NULL as the call to PyThreadState_GetDict()
+ above already checks if state is NULL */
+ cached_running_holder_tsid = PyThreadState_Get()->id;
+
return 0;
}