Skip to content

Commit

Permalink
Issue #608: Fix registration issue in objc-class
Browse files Browse the repository at this point in the history
The logic in objc_metaclass_register was off, resulting
in a race condition when using PyObjC in multiple threads
concurrently.

The two test scripts in Tools/free-threading now work
properly.
  • Loading branch information
ronaldoussoren committed Dec 22, 2024
1 parent 2b52eb8 commit 13295c9
Showing 1 changed file with 11 additions and 10 deletions.
21 changes: 11 additions & 10 deletions pyobjc-core/Modules/objc/objc-class.m
Original file line number Diff line number Diff line change
Expand Up @@ -228,23 +228,24 @@
NSMapInsert(class_registry, objc_meta_class, meta_class);
}

PyTypeObject* existing_meta = NSMapGet(metaclass_to_class, meta_class);
Class existing_meta = NSMapGet(metaclass_to_class, meta_class);
if (existing_meta) {
if (existing_meta != (PyTypeObject*)existing_class) {
PyErr_Format(PyObjCExc_Error, "Inconsistent mapping for class/metaclass '%s'",
class_getName(objc_class));
if (existing_class) {
Py_INCREF(meta_class);
#ifdef Py_GIL_DISABLED
PyMutex_Unlock(&registry_lock);
PyMutex_Unlock(&classmap_lock);
#endif
return NULL;
}
Py_INCREF(existing_meta);
return meta_class;
} else {
PyErr_Format(PyObjCExc_InternalError,
"Registering metaclass twice for '%s'", class_getName(existing_meta));
#ifdef Py_GIL_DISABLED
PyMutex_Unlock(&registry_lock);
PyMutex_Unlock(&classmap_lock);
PyMutex_Unlock(&registry_lock);
PyMutex_Unlock(&classmap_lock);
#endif
return existing_meta;
return NULL;
}
// LCOV_EXCL_STOP
}

Expand Down

0 comments on commit 13295c9

Please sign in to comment.