]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-127945: change `_ctypes_test.c` static globals to thread local (#132575)
authorKumar Aditya <kumaraditya@python.org>
Wed, 16 Apr 2025 17:41:27 +0000 (23:11 +0530)
committerGitHub <noreply@github.com>
Wed, 16 Apr 2025 17:41:27 +0000 (23:11 +0530)
Lib/test/test_ctypes/test_cfuncs.py
Lib/test/test_ctypes/test_structures.py
Modules/_ctypes/_ctypes_test.c

index e0c124607cb2e92dd66cfd38e52509dea26100f4..937be8eaa95c19d6056d7c6a873f8910bd9574c0 100644 (file)
@@ -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
index 67616086b1907c2e9055efbce8d485bcc3df30bd..bd7aba6376d167ac6284f6452bb782053fbee5e8 100644 (file)
@@ -284,7 +284,9 @@ class StructureTestCase(unittest.TestCase, StructCheckMixin):
         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)
 
index 7bac592fd38fb925798e1f5f265332623ee864e1..2268072545f45da42ca45bc1701492fb1af7e110 100644 (file)
 
 #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},