@@ -5326,13 +5326,13 @@ static PyType_Spec pycsimple_spec = {
53265326 PyCPointer_Type
53275327*/
53285328static PyObject *
5329- Pointer_item (PyObject * myself , Py_ssize_t index )
5329+ Pointer_item_lock_held (PyObject * myself , Py_ssize_t index )
53305330{
53315331 CDataObject * self = _CDataObject_CAST (myself );
53325332 Py_ssize_t size ;
53335333 Py_ssize_t offset ;
53345334 PyObject * proto ;
5335- void * deref = locked_deref ( self ) ;
5335+ void * deref = * ( void * * ) self -> b_ptr ;
53365336
53375337 if (deref == NULL ) {
53385338 PyErr_SetString (PyExc_ValueError ,
@@ -5364,8 +5364,23 @@ Pointer_item(PyObject *myself, Py_ssize_t index)
53645364 index , size , (char * )((char * )deref + offset ));
53655365}
53665366
5367+ static PyObject *
5368+ Pointer_item (PyObject * myself , Py_ssize_t index )
5369+ {
5370+ CDataObject * self = _CDataObject_CAST (myself );
5371+ PyObject * res ;
5372+ // TODO: The plan is to make LOCK_PTR() a mutex instead of a critical
5373+ // section someday, so when that happens, this needs to get refactored
5374+ // to be re-entrant safe.
5375+ // This goes for all the locks here.
5376+ LOCK_PTR (self );
5377+ res = Pointer_item_lock_held (myself , index );
5378+ UNLOCK_PTR (self );
5379+ return res ;
5380+ }
5381+
53675382static int
5368- Pointer_ass_item (PyObject * myself , Py_ssize_t index , PyObject * value )
5383+ Pointer_ass_item_lock_held (PyObject * myself , Py_ssize_t index , PyObject * value )
53695384{
53705385 CDataObject * self = _CDataObject_CAST (myself );
53715386 Py_ssize_t size ;
@@ -5378,7 +5393,7 @@ Pointer_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value)
53785393 return -1 ;
53795394 }
53805395
5381- void * deref = locked_deref ( self ) ;
5396+ void * deref = * ( void * * ) self -> b_ptr ;
53825397 if (deref == NULL ) {
53835398 PyErr_SetString (PyExc_ValueError ,
53845399 "NULL pointer access" );
@@ -5409,10 +5424,21 @@ Pointer_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value)
54095424 index , size , ((char * )deref + offset ));
54105425}
54115426
5427+ static int
5428+ Pointer_ass_item (PyObject * myself , Py_ssize_t index , PyObject * value )
5429+ {
5430+ CDataObject * self = _CDataObject_CAST (myself );
5431+ int res ;
5432+ LOCK_PTR (self );
5433+ res = Pointer_ass_item_lock_held (myself , index , value );
5434+ UNLOCK_PTR (self );
5435+ return res ;
5436+ }
5437+
54125438static PyObject *
5413- Pointer_get_contents (PyObject * self , void * closure )
5439+ Pointer_get_contents_lock_held (PyObject * self , void * closure )
54145440{
5415- void * deref = locked_deref ( _CDataObject_CAST (self )) ;
5441+ void * deref = * ( void * * ) _CDataObject_CAST (self )-> b_ptr ;
54165442 if (deref == NULL ) {
54175443 PyErr_SetString (PyExc_ValueError ,
54185444 "NULL pointer access" );
@@ -5429,6 +5455,17 @@ Pointer_get_contents(PyObject *self, void *closure)
54295455 return PyCData_FromBaseObj (st , stginfo -> proto , self , 0 , deref );
54305456}
54315457
5458+ static PyObject *
5459+ Pointer_get_contents (PyObject * myself , void * closure )
5460+ {
5461+ CDataObject * self = _CDataObject_CAST (myself );
5462+ PyObject * res ;
5463+ LOCK_PTR (self );
5464+ res = Pointer_get_contents_lock_held (myself , closure );
5465+ UNLOCK_PTR (self );
5466+ return res ;
5467+ }
5468+
54325469static int
54335470Pointer_set_contents (PyObject * op , PyObject * value , void * closure )
54345471{
@@ -5462,7 +5499,10 @@ Pointer_set_contents(PyObject *op, PyObject *value, void *closure)
54625499 }
54635500
54645501 dst = (CDataObject * )value ;
5502+ assert (dst != self ); // XXX Can the user do this?
5503+ LOCK_PTR (dst );
54655504 locked_deref_assign (self , dst -> b_ptr );
5505+ UNLOCK_PTR (dst );
54665506
54675507 /*
54685508 A Pointer instance must keep the value it points to alive. So, a
@@ -5514,6 +5554,22 @@ Pointer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
55145554 return generic_pycdata_new (st , type , args , kw );
55155555}
55165556
5557+ static int
5558+ copy_pointer_to_list_lock_held (PyObject * myself , PyObject * np , Py_ssize_t start , Py_ssize_t step )
5559+ {
5560+ Py_ssize_t i , len ;
5561+ size_t cur ;
5562+ for (cur = start , i = 0 ; i < len ; cur += step , i ++ ) {
5563+ PyObject * v = Pointer_item_lock_held (myself , cur );
5564+ if (!v ) {
5565+ return -1 ;
5566+ }
5567+ PyList_SET_ITEM (np , i , v );
5568+ }
5569+
5570+ return 0 ;
5571+ }
5572+
55175573static PyObject *
55185574Pointer_subscript (PyObject * myself , PyObject * item )
55195575{
@@ -5595,14 +5651,14 @@ Pointer_subscript(PyObject *myself, PyObject *item)
55955651 }
55965652 assert (iteminfo );
55975653 if (iteminfo -> getfunc == _ctypes_get_fielddesc ("c" )-> getfunc ) {
5598- char * ptr = locked_deref (self );
55995654 char * dest ;
56005655
56015656 if (len <= 0 )
56025657 return Py_GetConstant (Py_CONSTANT_EMPTY_BYTES );
56035658 if (step == 1 ) {
56045659 PyObject * res ;
56055660 LOCK_PTR (self );
5661+ char * ptr = * (void * * )self -> b_ptr ;
56065662 res = PyBytes_FromStringAndSize (ptr + start ,
56075663 len );
56085664 UNLOCK_PTR (self );
@@ -5612,6 +5668,7 @@ Pointer_subscript(PyObject *myself, PyObject *item)
56125668 if (dest == NULL )
56135669 return PyErr_NoMemory ();
56145670 LOCK_PTR (self );
5671+ char * ptr = * (void * * )self -> b_ptr ;
56155672 for (cur = start , i = 0 ; i < len ; cur += step , i ++ ) {
56165673 dest [i ] = ptr [cur ];
56175674 }
@@ -5621,14 +5678,14 @@ Pointer_subscript(PyObject *myself, PyObject *item)
56215678 return np ;
56225679 }
56235680 if (iteminfo -> getfunc == _ctypes_get_fielddesc ("u" )-> getfunc ) {
5624- wchar_t * ptr = locked_deref (self );
56255681 wchar_t * dest ;
56265682
56275683 if (len <= 0 )
56285684 return Py_GetConstant (Py_CONSTANT_EMPTY_STR );
56295685 if (step == 1 ) {
56305686 PyObject * res ;
56315687 LOCK_PTR (self );
5688+ wchar_t * ptr = * (void * * )self ;
56325689 res = PyUnicode_FromWideChar (ptr + start ,
56335690 len );
56345691 UNLOCK_PTR (self );
@@ -5638,6 +5695,7 @@ Pointer_subscript(PyObject *myself, PyObject *item)
56385695 if (dest == NULL )
56395696 return PyErr_NoMemory ();
56405697 LOCK_PTR (self );
5698+ wchar_t * ptr = * (void * * )self ;
56415699 for (cur = start , i = 0 ; i < len ; cur += step , i ++ ) {
56425700 dest [i ] = ptr [cur ];
56435701 }
@@ -5651,14 +5709,15 @@ Pointer_subscript(PyObject *myself, PyObject *item)
56515709 if (np == NULL )
56525710 return NULL ;
56535711
5654- for ( cur = start , i = 0 ; i < len ; cur += step , i ++ ) {
5655- PyObject * v = Pointer_item ( myself , cur );
5656- if (! v ) {
5657- Py_DECREF ( np );
5658- return NULL ;
5659- }
5660- PyList_SET_ITEM ( np , i , v ) ;
5712+ int res ;
5713+ LOCK_PTR ( self );
5714+ res = copy_pointer_to_list_lock_held ( myself , np , start , step );
5715+ UNLOCK_PTR ( self );
5716+ if ( res < 0 ) {
5717+ Py_DECREF ( np );
5718+ return NULL ;
56615719 }
5720+
56625721 return np ;
56635722 }
56645723 else {
0 commit comments