https://github.com/python/cpython/commit/f7a8bc50db5eda46ba1151cd966050206ac65a0f
commit: f7a8bc50db5eda46ba1151cd966050206ac65a0f
branch: main
author: Kumar Aditya <[email protected]>
committer: kumaraditya303 <[email protected]>
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 -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]