]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-141563: make `PyDateTime_IMPORT` thread-safe (#144210)
authorKumar Aditya <kumaraditya@python.org>
Mon, 9 Feb 2026 13:20:35 +0000 (18:50 +0530)
committerGitHub <noreply@github.com>
Mon, 9 Feb 2026 13:20:35 +0000 (13:20 +0000)
Include/datetime.h
Misc/NEWS.d/next/Core_and_Builtins/2026-02-02-17-07-34.gh-issue-141563.GheXjr.rst [new file with mode: 0644]

index ed36e6e48c87d255a55d22a3fa9df8771064b8e5..ed7e55009d2208315244c8a9900f794db20ca9ff 100644 (file)
@@ -196,8 +196,23 @@ typedef struct {
 /* Define global variable for the C API and a macro for setting it. */
 static PyDateTime_CAPI *PyDateTimeAPI = NULL;
 
-#define PyDateTime_IMPORT \
-    PyDateTimeAPI = (PyDateTime_CAPI *)PyCapsule_Import(PyDateTime_CAPSULE_NAME, 0)
+static inline PyDateTime_CAPI *
+_PyDateTime_IMPORT(void) {
+    PyDateTime_CAPI *val = _Py_atomic_load_ptr(&PyDateTimeAPI);
+    if (val == NULL) {
+        PyDateTime_CAPI *capi = (PyDateTime_CAPI *)PyCapsule_Import(
+            PyDateTime_CAPSULE_NAME, 0);
+        if (capi != NULL) {
+            /* if the compare exchange fails then in that case
+               another thread would have initialized it */
+            _Py_atomic_compare_exchange_ptr(&PyDateTimeAPI, &val, (void *)capi);
+            return capi;
+        }
+    }
+    return val;
+}
+
+#define PyDateTime_IMPORT _PyDateTime_IMPORT()
 
 /* Macro for access to the UTC singleton */
 #define PyDateTime_TimeZone_UTC PyDateTimeAPI->TimeZone_UTC
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-02-17-07-34.gh-issue-141563.GheXjr.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-02-17-07-34.gh-issue-141563.GheXjr.rst
new file mode 100644 (file)
index 0000000..4059525
--- /dev/null
@@ -0,0 +1 @@
+Fix thread safety of :c:macro:`! PyDateTime_IMPORT`.