Skip to content

Commit e3bec70

Browse files
wip
1 parent f3ef75e commit e3bec70

3 files changed

Lines changed: 24 additions & 23 deletions

File tree

Modules/_ctypes/_ctypes.c

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,7 @@ StructUnionType_init(PyObject *self, PyObject *args, PyObject *kwds, int isStruc
717717
ret = PyCStgInfo_clone(info, baseinfo);
718718
if (ret >= 0) {
719719
assert(stginfo_get_dict_final(info) == 0);
720-
stginfo_set_dict_final(baseinfo);
720+
stginfo_set_dict_final_lock_held(baseinfo);
721721
}
722722
STGINFO_UNLOCK2();
723723
return ret;
@@ -3177,11 +3177,7 @@ PyCData_FromBaseObj(ctypes_state *st,
31773177
return NULL;
31783178
}
31793179

3180-
if (stginfo_get_dict_final(info) != 1) {
3181-
STGINFO_LOCK(info);
3182-
stginfo_set_dict_final(info);
3183-
STGINFO_UNLOCK();
3184-
}
3180+
stginfo_set_dict_final(info);
31853181

31863182
assert(CDataObject_Check(st, cmem));
31873183
cmem->b_length = info->length;
@@ -3226,11 +3222,8 @@ PyCData_AtAddress(ctypes_state *st, PyObject *type, void *buf)
32263222
"abstract class");
32273223
return NULL;
32283224
}
3229-
if (stginfo_get_dict_final(info) != 1) {
3230-
STGINFO_LOCK(info);
3231-
stginfo_set_dict_final(info);
3232-
STGINFO_UNLOCK();
3233-
}
3225+
3226+
stginfo_set_dict_final(info);
32343227

32353228
pd = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
32363229
if (!pd) {
@@ -3464,11 +3457,8 @@ generic_pycdata_new(ctypes_state *st,
34643457
"abstract class");
34653458
return NULL;
34663459
}
3467-
if (stginfo_get_dict_final(info) != 1) {
3468-
STGINFO_LOCK(info);
3469-
stginfo_set_dict_final(info);
3470-
STGINFO_UNLOCK();
3471-
}
3460+
3461+
stginfo_set_dict_final(info);
34723462

34733463
obj = (CDataObject *)type->tp_alloc(type, 0);
34743464
if (!obj)

Modules/_ctypes/ctypes.h

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -411,20 +411,31 @@ typedef struct {
411411
#define STGINFO_UNLOCK() Py_END_CRITICAL_SECTION()
412412
#define STGINFO_UNLOCK2() Py_END_CRITICAL_SECTION2()
413413

414+
static inline int
415+
stginfo_get_dict_final(StgInfo *info)
416+
{
417+
return FT_ATOMIC_LOAD_INT(info->dict_final);
418+
}
419+
414420
static inline void
415-
stginfo_set_dict_final(StgInfo *info)
421+
stginfo_set_dict_final_lock_held(StgInfo *info)
416422
{
417423
_Py_CRITICAL_SECTION_ASSERT_MUTEX_LOCKED(&info->mutex);
418424
FT_ATOMIC_STORE_INT(info->dict_final, 1);
419425
}
420426

421-
static inline int
422-
stginfo_get_dict_final(StgInfo *info)
427+
static inline void
428+
stginfo_set_dict_final(StgInfo *info)
423429
{
424-
return FT_ATOMIC_LOAD_INT(info->dict_final);
430+
// avoid acquiring the lock if final is already set
431+
if (stginfo_get_dict_final(info) == 1) {
432+
return;
433+
}
434+
STGINFO_LOCK(info);
435+
stginfo_set_dict_final_lock_held(info);
436+
STGINFO_UNLOCK();
425437
}
426438

427-
428439
extern int PyCStgInfo_clone(StgInfo *dst_info, StgInfo *src_info);
429440
extern void ctype_clear_stginfo(StgInfo *info);
430441

Modules/_ctypes/stgdict.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ PyCStructUnionType_update_stginfo(PyObject *type, PyObject *fields, int isStruct
436436
if (info->flags & (TYPEFLAG_ISPOINTER | TYPEFLAG_HASPOINTER))
437437
stginfo->flags |= TYPEFLAG_HASPOINTER;
438438

439-
stginfo_set_dict_final(info); /* mark field type final */
439+
stginfo_set_dict_final_lock_held(info); /* mark field type final */
440440
STGINFO_UNLOCK();
441441
if (-1 == PyObject_SetAttr(type, prop->name, prop_obj)) {
442442
goto error;
@@ -476,7 +476,7 @@ PyCStructUnionType_update_stginfo(PyObject *type, PyObject *fields, int isStruct
476476
"Structure or union cannot contain itself");
477477
goto error;
478478
}
479-
stginfo_set_dict_final(stginfo);
479+
stginfo_set_dict_final_lock_held(stginfo);
480480

481481
retval = MakeAnonFields(type);
482482
error:;

0 commit comments

Comments
 (0)