@@ -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,15 @@ Pointer_set_contents(PyObject *op, PyObject *value, void *closure)
54625499 }
54635500
54645501 dst = (CDataObject * )value ;
5465- locked_deref_assign (self , dst -> b_ptr );
5502+ if (dst != self ) {
5503+ LOCK_PTR (dst );
5504+ locked_deref_assign (self , dst -> b_ptr );
5505+ UNLOCK_PTR (dst );
5506+ } else {
5507+ LOCK_PTR (self );
5508+ * ((void * * )self -> b_ptr ) = dst -> b_ptr ;
5509+ UNLOCK_PTR (self );
5510+ }
54665511
54675512 /*
54685513 A Pointer instance must keep the value it points to alive. So, a
@@ -5514,6 +5559,23 @@ Pointer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
55145559 return generic_pycdata_new (st , type , args , kw );
55155560}
55165561
5562+ static int
5563+ copy_pointer_to_list_lock_held (PyObject * myself , PyObject * np , Py_ssize_t len ,
5564+ Py_ssize_t start , Py_ssize_t step )
5565+ {
5566+ Py_ssize_t i ;
5567+ size_t cur ;
5568+ for (cur = start , i = 0 ; i < len ; cur += step , i ++ ) {
5569+ PyObject * v = Pointer_item_lock_held (myself , cur );
5570+ if (!v ) {
5571+ return -1 ;
5572+ }
5573+ PyList_SET_ITEM (np , i , v );
5574+ }
5575+
5576+ return 0 ;
5577+ }
5578+
55175579static PyObject *
55185580Pointer_subscript (PyObject * myself , PyObject * item )
55195581{
@@ -5595,14 +5657,14 @@ Pointer_subscript(PyObject *myself, PyObject *item)
55955657 }
55965658 assert (iteminfo );
55975659 if (iteminfo -> getfunc == _ctypes_get_fielddesc ("c" )-> getfunc ) {
5598- char * ptr = locked_deref (self );
55995660 char * dest ;
56005661
56015662 if (len <= 0 )
56025663 return Py_GetConstant (Py_CONSTANT_EMPTY_BYTES );
56035664 if (step == 1 ) {
56045665 PyObject * res ;
56055666 LOCK_PTR (self );
5667+ char * ptr = * (void * * )self -> b_ptr ;
56065668 res = PyBytes_FromStringAndSize (ptr + start ,
56075669 len );
56085670 UNLOCK_PTR (self );
@@ -5612,6 +5674,7 @@ Pointer_subscript(PyObject *myself, PyObject *item)
56125674 if (dest == NULL )
56135675 return PyErr_NoMemory ();
56145676 LOCK_PTR (self );
5677+ char * ptr = * (void * * )self -> b_ptr ;
56155678 for (cur = start , i = 0 ; i < len ; cur += step , i ++ ) {
56165679 dest [i ] = ptr [cur ];
56175680 }
@@ -5621,14 +5684,14 @@ Pointer_subscript(PyObject *myself, PyObject *item)
56215684 return np ;
56225685 }
56235686 if (iteminfo -> getfunc == _ctypes_get_fielddesc ("u" )-> getfunc ) {
5624- wchar_t * ptr = locked_deref (self );
56255687 wchar_t * dest ;
56265688
56275689 if (len <= 0 )
56285690 return Py_GetConstant (Py_CONSTANT_EMPTY_STR );
56295691 if (step == 1 ) {
56305692 PyObject * res ;
56315693 LOCK_PTR (self );
5694+ wchar_t * ptr = * (wchar_t * * )self -> b_ptr ;
56325695 res = PyUnicode_FromWideChar (ptr + start ,
56335696 len );
56345697 UNLOCK_PTR (self );
@@ -5638,6 +5701,7 @@ Pointer_subscript(PyObject *myself, PyObject *item)
56385701 if (dest == NULL )
56395702 return PyErr_NoMemory ();
56405703 LOCK_PTR (self );
5704+ wchar_t * ptr = * (wchar_t * * )self -> b_ptr ;
56415705 for (cur = start , i = 0 ; i < len ; cur += step , i ++ ) {
56425706 dest [i ] = ptr [cur ];
56435707 }
@@ -5651,14 +5715,15 @@ Pointer_subscript(PyObject *myself, PyObject *item)
56515715 if (np == NULL )
56525716 return NULL ;
56535717
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 ) ;
5718+ int res ;
5719+ LOCK_PTR ( self );
5720+ res = copy_pointer_to_list_lock_held ( myself , np , len , start , step );
5721+ UNLOCK_PTR ( self );
5722+ if ( res < 0 ) {
5723+ Py_DECREF ( np );
5724+ return NULL ;
56615725 }
5726+
56625727 return np ;
56635728 }
56645729 else {
0 commit comments