https://github.com/python/cpython/commit/0dba59e6899cd0b1717e3c1dc6110b18c91b0f8f commit: 0dba59e6899cd0b1717e3c1dc6110b18c91b0f8f branch: main author: Kumar Aditya <kumaradi...@python.org> committer: kumaraditya303 <kumaradi...@python.org> date: 2025-04-06T16:21:44+05:30 summary:
gh-128182: add critical sections to ctypes arrays getters and setters (#132152) 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 f3b15226f028e5..2e5dfb7ffbf9d5 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -1425,14 +1425,24 @@ static PyType_Spec pycpointer_type_spec = { PyCArrayType_init ensures that the new Array subclass created has a _length_ attribute, and a _type_ attribute. */ +/*[clinic input] +class _ctypes.PyCArrayType_Type "CDataObject *" "clinic_state()->PyCArrayType_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6340cbaead1bf3f3]*/ + +/*[clinic input] +@critical_section +@setter +_ctypes.PyCArrayType_Type.raw +[clinic start generated code]*/ static int -CharArray_set_raw(PyObject *op, PyObject *value, void *Py_UNUSED(ignored)) +_ctypes_PyCArrayType_Type_raw_set_impl(CDataObject *self, PyObject *value) +/*[clinic end generated code: output=cf9b2a9fd92e9ecb input=a3717561efc45efd]*/ { char *ptr; Py_ssize_t size; Py_buffer view; - CDataObject *self = _CDataObject_CAST(op); if (value == NULL) { PyErr_SetString(PyExc_AttributeError, "cannot delete attribute"); @@ -1457,39 +1467,51 @@ CharArray_set_raw(PyObject *op, PyObject *value, void *Py_UNUSED(ignored)) return -1; } +/*[clinic input] +@critical_section +@getter +_ctypes.PyCArrayType_Type.raw +[clinic start generated code]*/ + static PyObject * -CharArray_get_raw(PyObject *op, void *Py_UNUSED(ignored)) +_ctypes_PyCArrayType_Type_raw_get_impl(CDataObject *self) +/*[clinic end generated code: output=3a90be6f43764e31 input=4c49bbb715235ba7]*/ { - PyObject *res; - CDataObject *self = _CDataObject_CAST(op); - LOCK_PTR(self); - res = PyBytes_FromStringAndSize(self->b_ptr, self->b_size); - UNLOCK_PTR(self); - return res; + return PyBytes_FromStringAndSize(self->b_ptr, self->b_size); } +/*[clinic input] +@critical_section +@getter +_ctypes.PyCArrayType_Type.value +[clinic start generated code]*/ + static PyObject * -CharArray_get_value(PyObject *op, void *Py_UNUSED(ignored)) +_ctypes_PyCArrayType_Type_value_get_impl(CDataObject *self) +/*[clinic end generated code: output=fb0636f4d8875483 input=2432a2aeb1ed78d1]*/ { Py_ssize_t i; PyObject *res; - CDataObject *self = _CDataObject_CAST(op); - LOCK_PTR(self); char *ptr = self->b_ptr; for (i = 0; i < self->b_size; ++i) if (*ptr++ == '\0') break; res = PyBytes_FromStringAndSize(self->b_ptr, i); - UNLOCK_PTR(self); return res; } +/*[clinic input] +@critical_section +@setter +_ctypes.PyCArrayType_Type.value +[clinic start generated code]*/ + static int -CharArray_set_value(PyObject *op, PyObject *value, void *Py_UNUSED(ignored)) +_ctypes_PyCArrayType_Type_value_set_impl(CDataObject *self, PyObject *value) +/*[clinic end generated code: output=39ad655636a28dd5 input=e2e6385fc6ab1a29]*/ { const char *ptr; Py_ssize_t size; - CDataObject *self = _CDataObject_CAST(op); if (value == NULL) { PyErr_SetString(PyExc_TypeError, @@ -1513,40 +1535,46 @@ CharArray_set_value(PyObject *op, PyObject *value, void *Py_UNUSED(ignored)) } ptr = PyBytes_AS_STRING(value); - LOCK_PTR(self); memcpy(self->b_ptr, ptr, size); if (size < self->b_size) self->b_ptr[size] = '\0'; - UNLOCK_PTR(self); Py_DECREF(value); return 0; } static PyGetSetDef CharArray_getsets[] = { - { "raw", CharArray_get_raw, CharArray_set_raw, "value", NULL }, - { "value", CharArray_get_value, CharArray_set_value, "string value" }, + _CTYPES_PYCARRAYTYPE_TYPE_RAW_GETSETDEF + _CTYPES_PYCARRAYTYPE_TYPE_VALUE_GETSETDEF { NULL, NULL } }; static PyObject * -WCharArray_get_value(PyObject *op, void *Py_UNUSED(ignored)) +WCharArray_get_value_lock_held(PyObject *op) { Py_ssize_t i; PyObject *res; CDataObject *self = _CDataObject_CAST(op); wchar_t *ptr = (wchar_t *)self->b_ptr; - LOCK_PTR(self); for (i = 0; i < self->b_size/(Py_ssize_t)sizeof(wchar_t); ++i) if (*ptr++ == (wchar_t)0) break; res = PyUnicode_FromWideChar((wchar_t *)self->b_ptr, i); - UNLOCK_PTR(self); + return res; +} + +static PyObject * +WCharArray_get_value(PyObject *op, void *Py_UNUSED(ignored)) +{ + PyObject *res; + Py_BEGIN_CRITICAL_SECTION(op); + res = WCharArray_get_value_lock_held(op); + Py_END_CRITICAL_SECTION(); return res; } static int -WCharArray_set_value(PyObject *op, PyObject *value, void *Py_UNUSED(ignored)) +WCharArray_set_value_lock_held(PyObject *op, PyObject *value) { CDataObject *self = _CDataObject_CAST(op); @@ -1575,12 +1603,20 @@ WCharArray_set_value(PyObject *op, PyObject *value, void *Py_UNUSED(ignored)) return -1; } Py_ssize_t rc; - LOCK_PTR(self); rc = PyUnicode_AsWideChar(value, (wchar_t *)self->b_ptr, size); - UNLOCK_PTR(self); return rc < 0 ? -1 : 0; } +static int +WCharArray_set_value(PyObject *op, PyObject *value, void *Py_UNUSED(ignored)) +{ + int rc; + Py_BEGIN_CRITICAL_SECTION(op); + rc = WCharArray_set_value_lock_held(op, value); + Py_END_CRITICAL_SECTION(); + return rc; +} + static PyGetSetDef WCharArray_getsets[] = { { "value", WCharArray_get_value, WCharArray_set_value, "string value" }, { NULL, NULL } @@ -2779,8 +2815,9 @@ static PyType_Spec pycfuncptr_type_spec = { static CDataObject * PyCData_GetContainer(CDataObject *self) { - while (self->b_base) + while (self->b_base) { self = self->b_base; + } if (self->b_objects == NULL) { if (self->b_length) { self->b_objects = PyDict_New(); @@ -6305,4 +6342,4 @@ PyMODINIT_FUNC PyInit__ctypes(void) { return PyModuleDef_Init(&_ctypesmodule); -} +} \ No newline at end of file diff --git a/Modules/_ctypes/clinic/_ctypes.c.h b/Modules/_ctypes/clinic/_ctypes.c.h index dd2eca3bd6cb13..92dfb8f83b7da6 100644 --- a/Modules/_ctypes/clinic/_ctypes.c.h +++ b/Modules/_ctypes/clinic/_ctypes.c.h @@ -407,6 +407,106 @@ PyCPointerType_from_param(PyObject *type, PyTypeObject *cls, PyObject *const *ar return return_value; } +#if !defined(_ctypes_PyCArrayType_Type_raw_DOCSTR) +# define _ctypes_PyCArrayType_Type_raw_DOCSTR NULL +#endif +#if defined(_CTYPES_PYCARRAYTYPE_TYPE_RAW_GETSETDEF) +# undef _CTYPES_PYCARRAYTYPE_TYPE_RAW_GETSETDEF +# define _CTYPES_PYCARRAYTYPE_TYPE_RAW_GETSETDEF {"raw", (getter)_ctypes_PyCArrayType_Type_raw_get, (setter)_ctypes_PyCArrayType_Type_raw_set, _ctypes_PyCArrayType_Type_raw_DOCSTR}, +#else +# define _CTYPES_PYCARRAYTYPE_TYPE_RAW_GETSETDEF {"raw", NULL, (setter)_ctypes_PyCArrayType_Type_raw_set, NULL}, +#endif + +static int +_ctypes_PyCArrayType_Type_raw_set_impl(CDataObject *self, PyObject *value); + +static int +_ctypes_PyCArrayType_Type_raw_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +{ + int return_value; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ctypes_PyCArrayType_Type_raw_set_impl((CDataObject *)self, value); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if !defined(_ctypes_PyCArrayType_Type_raw_DOCSTR) +# define _ctypes_PyCArrayType_Type_raw_DOCSTR NULL +#endif +#if defined(_CTYPES_PYCARRAYTYPE_TYPE_RAW_GETSETDEF) +# undef _CTYPES_PYCARRAYTYPE_TYPE_RAW_GETSETDEF +# define _CTYPES_PYCARRAYTYPE_TYPE_RAW_GETSETDEF {"raw", (getter)_ctypes_PyCArrayType_Type_raw_get, (setter)_ctypes_PyCArrayType_Type_raw_set, _ctypes_PyCArrayType_Type_raw_DOCSTR}, +#else +# define _CTYPES_PYCARRAYTYPE_TYPE_RAW_GETSETDEF {"raw", (getter)_ctypes_PyCArrayType_Type_raw_get, NULL, _ctypes_PyCArrayType_Type_raw_DOCSTR}, +#endif + +static PyObject * +_ctypes_PyCArrayType_Type_raw_get_impl(CDataObject *self); + +static PyObject * +_ctypes_PyCArrayType_Type_raw_get(PyObject *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ctypes_PyCArrayType_Type_raw_get_impl((CDataObject *)self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if !defined(_ctypes_PyCArrayType_Type_value_DOCSTR) +# define _ctypes_PyCArrayType_Type_value_DOCSTR NULL +#endif +#if defined(_CTYPES_PYCARRAYTYPE_TYPE_VALUE_GETSETDEF) +# undef _CTYPES_PYCARRAYTYPE_TYPE_VALUE_GETSETDEF +# define _CTYPES_PYCARRAYTYPE_TYPE_VALUE_GETSETDEF {"value", (getter)_ctypes_PyCArrayType_Type_value_get, (setter)_ctypes_PyCArrayType_Type_value_set, _ctypes_PyCArrayType_Type_value_DOCSTR}, +#else +# define _CTYPES_PYCARRAYTYPE_TYPE_VALUE_GETSETDEF {"value", (getter)_ctypes_PyCArrayType_Type_value_get, NULL, _ctypes_PyCArrayType_Type_value_DOCSTR}, +#endif + +static PyObject * +_ctypes_PyCArrayType_Type_value_get_impl(CDataObject *self); + +static PyObject * +_ctypes_PyCArrayType_Type_value_get(PyObject *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ctypes_PyCArrayType_Type_value_get_impl((CDataObject *)self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if !defined(_ctypes_PyCArrayType_Type_value_DOCSTR) +# define _ctypes_PyCArrayType_Type_value_DOCSTR NULL +#endif +#if defined(_CTYPES_PYCARRAYTYPE_TYPE_VALUE_GETSETDEF) +# undef _CTYPES_PYCARRAYTYPE_TYPE_VALUE_GETSETDEF +# define _CTYPES_PYCARRAYTYPE_TYPE_VALUE_GETSETDEF {"value", (getter)_ctypes_PyCArrayType_Type_value_get, (setter)_ctypes_PyCArrayType_Type_value_set, _ctypes_PyCArrayType_Type_value_DOCSTR}, +#else +# define _CTYPES_PYCARRAYTYPE_TYPE_VALUE_GETSETDEF {"value", NULL, (setter)_ctypes_PyCArrayType_Type_value_set, NULL}, +#endif + +static int +_ctypes_PyCArrayType_Type_value_set_impl(CDataObject *self, PyObject *value); + +static int +_ctypes_PyCArrayType_Type_value_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +{ + int return_value; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ctypes_PyCArrayType_Type_value_set_impl((CDataObject *)self, value); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + PyDoc_STRVAR(c_wchar_p_from_param__doc__, "from_param($self, value, /)\n" "--\n" @@ -900,4 +1000,4 @@ Simple_from_outparm(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py } return Simple_from_outparm_impl(self, cls); } -/*[clinic end generated code: output=bc7e53010b10b558 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9fb75bf7e9a17df2 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