https://github.com/python/cpython/commit/2925462411c3dd4a597d8a0919c65fa02697db76
commit: 2925462411c3dd4a597d8a0919c65fa02697db76
branch: main
author: Kumar Aditya <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2025-04-16T23:11:27+05:30
summary:
gh-127945: change `_ctypes_test.c` static globals to thread local (#132575)
files:
M Lib/test/test_ctypes/test_cfuncs.py
M Lib/test/test_ctypes/test_structures.py
M Modules/_ctypes/_ctypes_test.c
diff --git a/Lib/test/test_ctypes/test_cfuncs.py
b/Lib/test/test_ctypes/test_cfuncs.py
index e0c124607cb2e9..937be8eaa95c19 100644
--- a/Lib/test/test_ctypes/test_cfuncs.py
+++ b/Lib/test/test_ctypes/test_cfuncs.py
@@ -14,9 +14,10 @@ class CFunctions(unittest.TestCase):
_dll = CDLL(_ctypes_test.__file__)
def S(self):
- return c_longlong.in_dll(self._dll, "last_tf_arg_s").value
+ return _ctypes_test.get_last_tf_arg_s()
+
def U(self):
- return c_ulonglong.in_dll(self._dll, "last_tf_arg_u").value
+ return _ctypes_test.get_last_tf_arg_u()
def test_byte(self):
self._dll.tf_b.restype = c_byte
diff --git a/Lib/test/test_ctypes/test_structures.py
b/Lib/test/test_ctypes/test_structures.py
index 67616086b1907c..bd7aba6376d167 100644
--- a/Lib/test/test_ctypes/test_structures.py
+++ b/Lib/test/test_ctypes/test_structures.py
@@ -284,7 +284,9 @@ class X(Structure):
func(s)
self.assertEqual(s.first, 0xdeadbeef)
self.assertEqual(s.second, 0xcafebabe)
- got = X.in_dll(dll, "last_tfrsuv_arg")
+ dll.get_last_tfrsuv_arg.argtypes = ()
+ dll.get_last_tfrsuv_arg.restype = X
+ got = dll.get_last_tfrsuv_arg()
self.assertEqual(s.first, got.first)
self.assertEqual(s.second, got.second)
diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c
index 7bac592fd38fb9..2268072545f45d 100644
--- a/Modules/_ctypes/_ctypes_test.c
+++ b/Modules/_ctypes/_ctypes_test.c
@@ -13,6 +13,16 @@
#include <Python.h>
+#ifdef thread_local
+# define _Py_thread_local thread_local
+#elif __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__)
+# define _Py_thread_local _Thread_local
+#elif defined(_MSC_VER) /* AKA NT_THREADS */
+# define _Py_thread_local __declspec(thread)
+#elif defined(__GNUC__) /* includes clang */
+# define _Py_thread_local __thread
+#endif
+
#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX)
# include "../_complex.h" // csqrt()
# undef I // for _ctypes_test_generated.c.h
@@ -81,7 +91,7 @@ typedef struct {
} TestReg;
-EXPORT(TestReg) last_tfrsuv_arg = {0};
+_Py_thread_local TestReg last_tfrsuv_arg = {0};
EXPORT(void)
@@ -741,8 +751,8 @@ EXPORT(void) _py_func(void)
{
}
-EXPORT(long long) last_tf_arg_s = 0;
-EXPORT(unsigned long long) last_tf_arg_u = 0;
+_Py_thread_local long long last_tf_arg_s = 0;
+_Py_thread_local unsigned long long last_tf_arg_u = 0;
struct BITS {
signed int A: 1, B:2, C:3, D:4, E: 5, F: 6, G: 7, H: 8, I: 9;
@@ -827,10 +837,24 @@ EXPORT(int) unpack_bitfields_msvc(struct BITS_msvc *bits,
char name)
}
#endif
+PyObject *get_last_tf_arg_s(PyObject *self, PyObject *noargs)
+{
+ return PyLong_FromLongLong(last_tf_arg_s);
+}
+
+PyObject *get_last_tf_arg_u(PyObject *self, PyObject *noargs)
+{
+ return PyLong_FromUnsignedLongLong(last_tf_arg_u);
+}
+
+EXPORT(TestReg) get_last_tfrsuv_arg(void)
+{
+ return last_tfrsuv_arg;
+}
+
static PyMethodDef module_methods[] = {
-/* {"get_last_tf_arg_s", get_last_tf_arg_s, METH_NOARGS},
+ {"get_last_tf_arg_s", get_last_tf_arg_s, METH_NOARGS},
{"get_last_tf_arg_u", get_last_tf_arg_u, METH_NOARGS},
-*/
{"func_si", py_func_si, METH_VARARGS},
{"func", py_func, METH_NOARGS},
{"get_generated_test_data", get_generated_test_data, METH_O},
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]