https://github.com/python/cpython/commit/f7a8bc50db5eda46ba1151cd966050206ac65a0f
commit: f7a8bc50db5eda46ba1151cd966050206ac65a0f
branch: main
author: Kumar Aditya <kumaradi...@python.org>
committer: kumaraditya303 <kumaradi...@python.org>
date: 2025-04-05T15:24:58+05:30
summary:

gh-128182: add critical section to `_ctypes.PyCData` methods (#132082)

files:
M Modules/_ctypes/_ctypes.c
M Modules/_ctypes/clinic/_ctypes.c.h

diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
index efefc0157237bd..d6bcaa2c7aa958 100644
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -3007,7 +3007,8 @@ PyCData_nohash(PyObject *self)
 }
 
 /*[clinic input]
-_ctypes.PyCData.__reduce__ as PyCData_reduce
+@critical_section
+_ctypes.PyCData.__reduce__
 
     myself: self
     cls: defining_class
@@ -3015,8 +3016,8 @@ _ctypes.PyCData.__reduce__ as PyCData_reduce
 [clinic start generated code]*/
 
 static PyObject *
-PyCData_reduce_impl(PyObject *myself, PyTypeObject *cls)
-/*[clinic end generated code: output=1a025ccfdd8c935d input=34097a5226ea63c1]*/
+_ctypes_PyCData___reduce___impl(PyObject *myself, PyTypeObject *cls)
+/*[clinic end generated code: output=eaad97e111599294 input=6a464e1a1e2bbdbd]*/
 {
     CDataObject *self = _CDataObject_CAST(myself);
 
@@ -3037,33 +3038,33 @@ PyCData_reduce_impl(PyObject *myself, PyTypeObject *cls)
         return NULL;
     }
     PyObject *bytes;
-    LOCK_PTR(self);
     bytes = PyBytes_FromStringAndSize(self->b_ptr, self->b_size);
-    UNLOCK_PTR(self);
     return Py_BuildValue("O(O(NN))", st->_unpickle, Py_TYPE(myself), dict,
                          bytes);
 }
 
+/*[clinic input]
+@critical_section
+_ctypes.PyCData.__setstate__
+
+    myself: self
+    dict: object(subclass_of="&PyDict_Type")
+    data: str(accept={str, robuffer}, zeroes=True)
+    /
+[clinic start generated code]*/
+
 static PyObject *
-PyCData_setstate(PyObject *myself, PyObject *args)
+_ctypes_PyCData___setstate___impl(PyObject *myself, PyObject *dict,
+                                  const char *data, Py_ssize_t data_length)
+/*[clinic end generated code: output=8bd4c0a5b4f254bd input=124f5070258254c6]*/
 {
-    void *data;
-    Py_ssize_t len;
-    int res;
-    PyObject *dict, *mydict;
     CDataObject *self = _CDataObject_CAST(myself);
-    if (!PyArg_ParseTuple(args, "O!s#",
-                          &PyDict_Type, &dict, &data, &len))
-    {
-        return NULL;
+
+    if (data_length > self->b_size) {
+        data_length = self->b_size;
     }
-    if (len > self->b_size)
-        len = self->b_size;
-    // XXX Can we use locked_memcpy_to()?
-    LOCK_PTR(self);
-    memmove(self->b_ptr, data, len);
-    UNLOCK_PTR(self);
-    mydict = PyObject_GetAttrString(myself, "__dict__");
+    memmove(self->b_ptr, data, data_length);
+    PyObject *mydict = PyObject_GetAttrString(myself, "__dict__");
     if (mydict == NULL) {
         return NULL;
     }
@@ -3074,26 +3075,30 @@ PyCData_setstate(PyObject *myself, PyObject *args)
         Py_DECREF(mydict);
         return NULL;
     }
-    res = PyDict_Update(mydict, dict);
+    int res = PyDict_Update(mydict, dict);
     Py_DECREF(mydict);
     if (res == -1)
         return NULL;
     Py_RETURN_NONE;
 }
 
-/*
- * default __ctypes_from_outparam__ method returns self.
- */
+/*[clinic input]
+_ctypes.PyCData.__ctypes_from_outparam__
+
+default __ctypes_from_outparam__ method returns self.
+[clinic start generated code]*/
+
 static PyObject *
-PyCData_from_outparam(PyObject *self, PyObject *args)
+_ctypes_PyCData___ctypes_from_outparam___impl(PyObject *self)
+/*[clinic end generated code: output=a7facc849097b549 input=910c5fec33e268c9]*/
 {
     return Py_NewRef(self);
 }
 
 static PyMethodDef PyCData_methods[] = {
-    { "__ctypes_from_outparam__", PyCData_from_outparam, METH_NOARGS, },
-    PYCDATA_REDUCE_METHODDEF
-    { "__setstate__", PyCData_setstate, METH_VARARGS, },
+    _CTYPES_PYCDATA___CTYPES_FROM_OUTPARAM___METHODDEF
+    _CTYPES_PYCDATA___SETSTATE___METHODDEF
+    _CTYPES_PYCDATA___REDUCE___METHODDEF
     { NULL, NULL },
 };
 
diff --git a/Modules/_ctypes/clinic/_ctypes.c.h 
b/Modules/_ctypes/clinic/_ctypes.c.h
index 1f2e871137ed79..2b36f3592cc51c 100644
--- a/Modules/_ctypes/clinic/_ctypes.c.h
+++ b/Modules/_ctypes/clinic/_ctypes.c.h
@@ -581,25 +581,82 @@ PyCSimpleType_from_param(PyObject *type, PyTypeObject 
*cls, PyObject *const *arg
     return return_value;
 }
 
-PyDoc_STRVAR(PyCData_reduce__doc__,
+PyDoc_STRVAR(_ctypes_PyCData___reduce____doc__,
 "__reduce__($self, /)\n"
 "--\n"
 "\n");
 
-#define PYCDATA_REDUCE_METHODDEF    \
-    {"__reduce__", _PyCFunction_CAST(PyCData_reduce), 
METH_METHOD|METH_FASTCALL|METH_KEYWORDS, PyCData_reduce__doc__},
+#define _CTYPES_PYCDATA___REDUCE___METHODDEF    \
+    {"__reduce__", _PyCFunction_CAST(_ctypes_PyCData___reduce__), 
METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _ctypes_PyCData___reduce____doc__},
 
 static PyObject *
-PyCData_reduce_impl(PyObject *myself, PyTypeObject *cls);
+_ctypes_PyCData___reduce___impl(PyObject *myself, PyTypeObject *cls);
 
 static PyObject *
-PyCData_reduce(PyObject *myself, PyTypeObject *cls, PyObject *const *args, 
Py_ssize_t nargs, PyObject *kwnames)
+_ctypes_PyCData___reduce__(PyObject *myself, PyTypeObject *cls, PyObject 
*const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
+    PyObject *return_value = NULL;
+
     if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
         PyErr_SetString(PyExc_TypeError, "__reduce__() takes no arguments");
-        return NULL;
+        goto exit;
     }
-    return PyCData_reduce_impl(myself, cls);
+    Py_BEGIN_CRITICAL_SECTION(myself);
+    return_value = _ctypes_PyCData___reduce___impl(myself, cls);
+    Py_END_CRITICAL_SECTION();
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_ctypes_PyCData___setstate____doc__,
+"__setstate__($self, dict, data, /)\n"
+"--\n"
+"\n");
+
+#define _CTYPES_PYCDATA___SETSTATE___METHODDEF    \
+    {"__setstate__", _PyCFunction_CAST(_ctypes_PyCData___setstate__), 
METH_FASTCALL, _ctypes_PyCData___setstate____doc__},
+
+static PyObject *
+_ctypes_PyCData___setstate___impl(PyObject *myself, PyObject *dict,
+                                  const char *data, Py_ssize_t data_length);
+
+static PyObject *
+_ctypes_PyCData___setstate__(PyObject *myself, PyObject *const *args, 
Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    PyObject *dict;
+    const char *data;
+    Py_ssize_t data_length;
+
+    if (!_PyArg_ParseStack(args, nargs, "O!s#:__setstate__",
+        &PyDict_Type, &dict, &data, &data_length)) {
+        goto exit;
+    }
+    Py_BEGIN_CRITICAL_SECTION(myself);
+    return_value = _ctypes_PyCData___setstate___impl(myself, dict, data, 
data_length);
+    Py_END_CRITICAL_SECTION();
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_ctypes_PyCData___ctypes_from_outparam____doc__,
+"__ctypes_from_outparam__($self, /)\n"
+"--\n"
+"\n"
+"default __ctypes_from_outparam__ method returns self.");
+
+#define _CTYPES_PYCDATA___CTYPES_FROM_OUTPARAM___METHODDEF    \
+    {"__ctypes_from_outparam__", 
(PyCFunction)_ctypes_PyCData___ctypes_from_outparam__, METH_NOARGS, 
_ctypes_PyCData___ctypes_from_outparam____doc__},
+
+static PyObject *
+_ctypes_PyCData___ctypes_from_outparam___impl(PyObject *self);
+
+static PyObject *
+_ctypes_PyCData___ctypes_from_outparam__(PyObject *self, PyObject 
*Py_UNUSED(ignored))
+{
+    return _ctypes_PyCData___ctypes_from_outparam___impl(self);
 }
 
 #if !defined(_ctypes_CFuncPtr_errcheck_DOCSTR)
@@ -793,4 +850,4 @@ Simple_from_outparm(PyObject *self, PyTypeObject *cls, 
PyObject *const *args, Py
     }
     return Simple_from_outparm_impl(self, cls);
 }
-/*[clinic end generated code: output=a18d87239b6fb8ca input=a9049054013a1b77]*/
+/*[clinic end generated code: output=2a1d935e9d8ceadd input=a9049054013a1b77]*/

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to