Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd47584a

Browse files
gh-131336: fix thread safety for ctypes functions (#132232)
1 parenta26d58c commitd47584a

File tree

3 files changed

+211
-72
lines changed

3 files changed

+211
-72
lines changed

‎Modules/_ctypes/_ctypes.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2843,16 +2843,24 @@ PyCData_GetContainer(CDataObject *self)
28432843
while (self->b_base) {
28442844
self=self->b_base;
28452845
}
2846+
CDataObject*res=self;
2847+
Py_BEGIN_CRITICAL_SECTION(self);
2848+
// avoid using return directly in this block because critical section
2849+
// needs to be released before returning
28462850
if (self->b_objects==NULL) {
28472851
if (self->b_length) {
28482852
self->b_objects=PyDict_New();
2849-
if (self->b_objects==NULL)
2850-
returnNULL;
2853+
if (self->b_objects==NULL) {
2854+
res=NULL;
2855+
gotoexit;
2856+
}
28512857
}else {
28522858
self->b_objects=Py_NewRef(Py_None);
28532859
}
28542860
}
2855-
returnself;
2861+
exit:;
2862+
Py_END_CRITICAL_SECTION();
2863+
returnres;
28562864
}
28572865

28582866
staticPyObject*

‎Modules/_ctypes/callproc.c

Lines changed: 58 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,9 @@ module _ctypes
106106
#if defined(Py_HAVE_C_COMPLEX)&& defined(Py_FFI_SUPPORT_C_COMPLEX)
107107
#include"../_complex.h"// complex
108108
#endif
109-
109+
#defineclinic_state() (get_module_state(module))
110110
#include"clinic/callproc.c.h"
111+
#undef clinic_state
111112

112113
#defineCTYPES_CAPSULE_NAME_PYMEM "_ctypes pymem"
113114

@@ -1731,15 +1732,20 @@ call_cdeclfunction(PyObject *self, PyObject *args)
17311732
/*****************************************************************
17321733
* functions
17331734
*/
1734-
PyDoc_STRVAR(sizeof_doc,
1735-
"sizeof(C type) -> integer\n"
1736-
"sizeof(C instance) -> integer\n"
1737-
"Return the size in bytes of a C instance");
1735+
1736+
/*[clinic input]
1737+
_ctypes.sizeof
1738+
obj: object
1739+
/
1740+
Return the size in bytes of a C instance.
1741+
1742+
[clinic start generated code]*/
17381743

17391744
staticPyObject*
1740-
sizeof_func(PyObject*self,PyObject*obj)
1745+
_ctypes_sizeof(PyObject*module,PyObject*obj)
1746+
/*[clinic end generated code: output=ed38a3f364d7bd3e input=321fd0f65cb2d623]*/
17411747
{
1742-
ctypes_state*st=get_module_state(self);
1748+
ctypes_state*st=get_module_state(module);
17431749

17441750
StgInfo*info;
17451751
if (PyStgInfo_FromType(st,obj,&info)<0) {
@@ -1750,7 +1756,11 @@ sizeof_func(PyObject *self, PyObject *obj)
17501756
}
17511757

17521758
if (CDataObject_Check(st,obj)) {
1753-
returnPyLong_FromSsize_t(((CDataObject*)obj)->b_size);
1759+
PyObject*ret=NULL;
1760+
Py_BEGIN_CRITICAL_SECTION(obj);
1761+
ret=PyLong_FromSsize_t(((CDataObject*)obj)->b_size);
1762+
Py_END_CRITICAL_SECTION();
1763+
returnret;
17541764
}
17551765
PyErr_SetString(PyExc_TypeError,
17561766
"this type has no size");
@@ -1778,40 +1788,24 @@ align_func(PyObject *self, PyObject *obj)
17781788
returnNULL;
17791789
}
17801790

1781-
PyDoc_STRVAR(byref_doc,
1782-
"byref(C instance[, offset=0]) -> byref-object\n"
1783-
"Return a pointer lookalike to a C instance, only usable\n"
1784-
"as function argument");
17851791

1786-
/*
1787-
* We must return something which can be converted to a parameter,
1788-
* but still has a reference to self.
1789-
*/
1792+
/*[clinic input]
1793+
@critical_section obj
1794+
_ctypes.byref
1795+
obj: object(subclass_of="clinic_state()->PyCData_Type")
1796+
offset: Py_ssize_t = 0
1797+
/
1798+
Return a pointer lookalike to a C instance, only usable as function argument.
1799+
1800+
[clinic start generated code]*/
1801+
17901802
staticPyObject*
1791-
byref(PyObject*self,PyObject*args)
1803+
_ctypes_byref_impl(PyObject*module,PyObject*obj,Py_ssize_toffset)
1804+
/*[clinic end generated code: output=60dec5ed520c71de input=6ec02d95d15fbd56]*/
17921805
{
1793-
PyCArgObject*parg;
1794-
PyObject*obj;
1795-
PyObject*pyoffset=NULL;
1796-
Py_ssize_toffset=0;
1797-
1798-
if (!PyArg_UnpackTuple(args,"byref",1,2,
1799-
&obj,&pyoffset))
1800-
returnNULL;
1801-
if (pyoffset) {
1802-
offset=PyNumber_AsSsize_t(pyoffset,NULL);
1803-
if (offset==-1&&PyErr_Occurred())
1804-
returnNULL;
1805-
}
1806-
ctypes_state*st=get_module_state(self);
1807-
if (!CDataObject_Check(st,obj)) {
1808-
PyErr_Format(PyExc_TypeError,
1809-
"byref() argument must be a ctypes instance, not '%s'",
1810-
Py_TYPE(obj)->tp_name);
1811-
returnNULL;
1812-
}
1806+
ctypes_state*st=get_module_state(module);
18131807

1814-
parg=PyCArgObject_new(st);
1808+
PyCArgObject*parg=PyCArgObject_new(st);
18151809
if (parg==NULL)
18161810
returnNULL;
18171811

@@ -1822,19 +1816,19 @@ byref(PyObject *self, PyObject *args)
18221816
return (PyObject*)parg;
18231817
}
18241818

1825-
PyDoc_STRVAR(addressof_doc,
1826-
"addressof(C instance) -> integer\n"
1827-
"Return the address of the C instance internal buffer");
1819+
/*[clinic input]
1820+
@critical_section obj
1821+
_ctypes.addressof
1822+
obj: object(subclass_of="clinic_state()->PyCData_Type")
1823+
/
1824+
Return the address of the C instance internal buffer
1825+
1826+
[clinic start generated code]*/
18281827

18291828
staticPyObject*
1830-
addressof(PyObject*self,PyObject*obj)
1829+
_ctypes_addressof_impl(PyObject*module,PyObject*obj)
1830+
/*[clinic end generated code: output=30d8e80c4bab70c7 input=d83937d105d3a442]*/
18311831
{
1832-
ctypes_state*st=get_module_state(self);
1833-
if (!CDataObject_Check(st,obj)) {
1834-
PyErr_SetString(PyExc_TypeError,
1835-
"invalid type");
1836-
returnNULL;
1837-
}
18381832
if (PySys_Audit("ctypes.addressof","(O)",obj)<0) {
18391833
returnNULL;
18401834
}
@@ -1878,18 +1872,20 @@ My_Py_DECREF(PyObject *self, PyObject *arg)
18781872
returnarg;
18791873
}
18801874

1881-
staticPyObject*
1882-
resize(PyObject*self,PyObject*args)
1883-
{
1884-
CDataObject*obj;
1885-
Py_ssize_tsize;
1875+
/*[clinic input]
1876+
@critical_section obj
1877+
_ctypes.resize
1878+
obj: object(subclass_of="clinic_state()->PyCData_Type", type="CDataObject *")
1879+
size: Py_ssize_t
1880+
/
18861881
1887-
if (!PyArg_ParseTuple(args,
1888-
"On:resize",
1889-
&obj,&size))
1890-
returnNULL;
1882+
[clinic start generated code]*/
18911883

1892-
ctypes_state*st=get_module_state(self);
1884+
staticPyObject*
1885+
_ctypes_resize_impl(PyObject*module,CDataObject*obj,Py_ssize_tsize)
1886+
/*[clinic end generated code: output=11c89c7dbdbcd53f input=bf5a6aaea8514261]*/
1887+
{
1888+
ctypes_state*st=get_module_state(module);
18931889
StgInfo*info;
18941890
intresult=PyStgInfo_FromObject(st, (PyObject*)obj,&info);
18951891
if (result<0) {
@@ -2103,7 +2099,7 @@ PyMethodDef _ctypes_module_methods[] = {
21032099
CREATE_POINTER_INST_METHODDEF
21042100
{"_unpickle",unpickle,METH_VARARGS },
21052101
{"buffer_info",buffer_info,METH_O,"Return buffer interface information"},
2106-
{"resize",resize,METH_VARARGS,"Resize the memory buffer of a ctypes instance"},
2102+
_CTYPES_RESIZE_METHODDEF
21072103
#ifdefMS_WIN32
21082104
{"get_last_error",get_last_error,METH_NOARGS},
21092105
{"set_last_error",set_last_error,METH_VARARGS},
@@ -2122,19 +2118,13 @@ PyMethodDef _ctypes_module_methods[] = {
21222118
{"_dyld_shared_cache_contains_path",py_dyld_shared_cache_contains_path,METH_VARARGS,"check if path is in the shared cache"},
21232119
#endif
21242120
{"alignment",align_func,METH_O,alignment_doc},
2125-
{"sizeof",sizeof_func,METH_O,sizeof_doc},
2126-
{"byref",byref,METH_VARARGS,byref_doc},
2127-
{"addressof",addressof,METH_O,addressof_doc},
2121+
_CTYPES_SIZEOF_METHODDEF
2122+
_CTYPES_BYREF_METHODDEF
2123+
_CTYPES_ADDRESSOF_METHODDEF
21282124
{"call_function",call_function,METH_VARARGS },
21292125
{"call_cdeclfunction",call_cdeclfunction,METH_VARARGS },
21302126
{"PyObj_FromPtr",My_PyObj_FromPtr,METH_VARARGS },
21312127
{"Py_INCREF",My_Py_INCREF,METH_O },
21322128
{"Py_DECREF",My_Py_DECREF,METH_O },
21332129
{NULL,NULL}/* Sentinel */
21342130
};
2135-
2136-
/*
2137-
Local Variables:
2138-
compile-command: "cd .. && python setup.py -q build -g && python setup.py -q build install --home ~"
2139-
End:
2140-
*/

‎Modules/_ctypes/clinic/callproc.c.h

Lines changed: 142 additions & 1 deletion
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp