From c3f4649b7de5e8703ff320efbd36a4e818202a6b Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Sat, 24 Jan 2026 15:11:51 +0530 Subject: [PATCH 1/2] make PyDateTime_IMPORT thread-safe --- Include/datetime.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Include/datetime.h b/Include/datetime.h index ed36e6e48c87d2..6473a420602d2f 100644 --- a/Include/datetime.h +++ b/Include/datetime.h @@ -197,7 +197,18 @@ typedef struct { static PyDateTime_CAPI *PyDateTimeAPI = NULL; #define PyDateTime_IMPORT \ - PyDateTimeAPI = (PyDateTime_CAPI *)PyCapsule_Import(PyDateTime_CAPSULE_NAME, 0) + do { \ + void *val = _Py_atomic_load_ptr(&PyDateTimeAPI); \ + if (val == NULL) { \ + PyDateTime_CAPI *capi = (PyDateTime_CAPI *)PyCapsule_Import( \ + PyDateTime_CAPSULE_NAME, 0); \ + if (capi != NULL) { \ + /* it is okay if the compare exchange fails as in that case + another thread would have initialized it */ \ + _Py_atomic_compare_exchange_ptr(&PyDateTimeAPI, &val, (void *)capi); \ + } \ + } \ + } while (0) /* Macro for access to the UTC singleton */ #define PyDateTime_TimeZone_UTC PyDateTimeAPI->TimeZone_UTC From 36a06c8b4ab63104b459127f942ed6e02967b17b Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Sat, 24 Jan 2026 18:51:18 +0530 Subject: [PATCH 2/2] use static inline function --- Include/datetime.h | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/Include/datetime.h b/Include/datetime.h index 6473a420602d2f..29a578cb59ad5f 100644 --- a/Include/datetime.h +++ b/Include/datetime.h @@ -196,19 +196,21 @@ typedef struct { /* Define global variable for the C API and a macro for setting it. */ static PyDateTime_CAPI *PyDateTimeAPI = NULL; -#define PyDateTime_IMPORT \ - do { \ - void *val = _Py_atomic_load_ptr(&PyDateTimeAPI); \ - if (val == NULL) { \ - PyDateTime_CAPI *capi = (PyDateTime_CAPI *)PyCapsule_Import( \ - PyDateTime_CAPSULE_NAME, 0); \ - if (capi != NULL) { \ - /* it is okay if the compare exchange fails as in that case - another thread would have initialized it */ \ - _Py_atomic_compare_exchange_ptr(&PyDateTimeAPI, &val, (void *)capi); \ - } \ - } \ - } while (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; +} /* Macro for access to the UTC singleton */ #define PyDateTime_TimeZone_UTC PyDateTimeAPI->TimeZone_UTC