Skip to content

Commit 0a27451

Browse files
committed
Fix usages of locked_deref()
1 parent 3b3720f commit 0a27451

1 file changed

Lines changed: 74 additions & 15 deletions

File tree

Modules/_ctypes/_ctypes.c

Lines changed: 74 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5326,13 +5326,13 @@ static PyType_Spec pycsimple_spec = {
53265326
PyCPointer_Type
53275327
*/
53285328
static 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+
53675382
static 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+
54125438
static 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+
54325469
static int
54335470
Pointer_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+
55175573
static PyObject *
55185574
Pointer_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

Comments
 (0)