Skip to content

Commit 8bb980f

Browse files
committed
Add a lock for generic helper functions.
1 parent d01b757 commit 8bb980f

File tree

1 file changed

+25
-7
lines changed

1 file changed

+25
-7
lines changed

Modules/_ctypes/_ctypes.c

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3216,7 +3216,6 @@ PyCData_AtAddress(ctypes_state *st, PyObject *type, void *buf)
32163216
return NULL;
32173217
}
32183218
assert(CDataObject_Check(st, pd));
3219-
// XXX Use an atomic load if the size is 1, 2, 4, or 8 bytes?
32203219
pd->b_ptr = (char *)buf;
32213220
pd->b_length = info->length;
32223221
pd->b_size = info->size;
@@ -3242,15 +3241,23 @@ PyObject *
32423241
PyCData_get(ctypes_state *st, PyObject *type, GETFUNC getfunc, PyObject *src,
32433242
Py_ssize_t index, Py_ssize_t size, char *adr)
32443243
{
3245-
if (getfunc)
3246-
return getfunc(adr, size);
3244+
CDataObject *cdata = (CDataObject *)src;
3245+
if (getfunc) {
3246+
LOCK_PTR(cdata);
3247+
PyObject *res = getfunc(adr, size);
3248+
UNLOCK_PTR(cdata);
3249+
return res;
3250+
}
32473251
assert(type);
32483252
StgInfo *info;
32493253
if (PyStgInfo_FromType(st, type, &info) < 0) {
32503254
return NULL;
32513255
}
32523256
if (info && info->getfunc && !_ctypes_simple_instance(st, type)) {
3253-
return info->getfunc(adr, size);
3257+
LOCK_PTR(cdata);
3258+
PyObject *res = info->getfunc(adr, size);
3259+
UNLOCK_PTR(cdata);
3260+
return res;
32543261
}
32553262
return PyCData_FromBaseObj(st, type, src, index, adr);
32563263
}
@@ -3267,15 +3274,22 @@ _PyCData_set(ctypes_state *st,
32673274
int err;
32683275

32693276
if (setfunc) {
3270-
return setfunc(ptr, value, size);
3277+
LOCK_PTR(dst);
3278+
PyObject *res = setfunc(ptr, value, size);
3279+
UNLOCK_PTR(dst);
3280+
return res;
32713281
}
32723282
if (!CDataObject_Check(st, value)) {
32733283
StgInfo *info;
32743284
if (PyStgInfo_FromType(st, type, &info) < 0) {
32753285
return NULL;
32763286
}
3277-
if (info && info->setfunc)
3278-
return info->setfunc(ptr, value, size);
3287+
if (info && info->setfunc) {
3288+
LOCK_PTR(dst);
3289+
PyObject *res = info->setfunc(ptr, value, size);
3290+
UNLOCK_PTR(dst);
3291+
return res;
3292+
}
32793293
/*
32803294
If value is a tuple, we try to call the type with the tuple
32813295
and use the result!
@@ -3295,7 +3309,9 @@ _PyCData_set(ctypes_state *st,
32953309
Py_DECREF(ob);
32963310
return result;
32973311
} else if (value == Py_None && PyCPointerTypeObject_Check(st, type)) {
3312+
LOCK_PTR(dst);
32983313
*(void **)ptr = NULL;
3314+
UNLOCK_PTR(dst);
32993315
Py_RETURN_NONE;
33003316
} else {
33013317
PyErr_Format(PyExc_TypeError,
@@ -3345,7 +3361,9 @@ _PyCData_set(ctypes_state *st,
33453361
((PyTypeObject *)type)->tp_name);
33463362
return NULL;
33473363
}
3364+
LOCK_PTR(dst);
33483365
*(void **)ptr = src->b_ptr;
3366+
UNLOCK_PTR(dst);
33493367

33503368
keep = GetKeepedObjects(src);
33513369
if (keep == NULL)

0 commit comments

Comments
 (0)