mirror of
https://github.com/python/cpython.git
synced 2025-07-07 19:35:27 +00:00
gh-128182: add critical sections to ctypes arrays getters and setters (#132152)
This commit is contained in:
parent
0a10b45dd1
commit
0dba59e689
2 changed files with 168 additions and 31 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
CharArray_get_raw(PyObject *op, void *Py_UNUSED(ignored))
|
||||
{
|
||||
PyObject *res;
|
||||
CDataObject *self = _CDataObject_CAST(op);
|
||||
LOCK_PTR(self);
|
||||
res = PyBytes_FromStringAndSize(self->b_ptr, self->b_size);
|
||||
UNLOCK_PTR(self);
|
||||
return res;
|
||||
}
|
||||
/*[clinic input]
|
||||
@critical_section
|
||||
@getter
|
||||
_ctypes.PyCArrayType_Type.raw
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
CharArray_get_value(PyObject *op, void *Py_UNUSED(ignored))
|
||||
_ctypes_PyCArrayType_Type_raw_get_impl(CDataObject *self)
|
||||
/*[clinic end generated code: output=3a90be6f43764e31 input=4c49bbb715235ba7]*/
|
||||
{
|
||||
return PyBytes_FromStringAndSize(self->b_ptr, self->b_size);
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
@critical_section
|
||||
@getter
|
||||
_ctypes.PyCArrayType_Type.value
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
_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);
|
||||
}
|
||||
}
|
102
Modules/_ctypes/clinic/_ctypes.c.h
generated
102
Modules/_ctypes/clinic/_ctypes.c.h
generated
|
@ -407,6 +407,106 @@ exit:
|
|||
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]*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue