Skip to content

Commit

Permalink
Issue #608: audit module.m
Browse files Browse the repository at this point in the history
"module.m" is now compatible with free-threading.
  • Loading branch information
ronaldoussoren committed Dec 7, 2024
1 parent 9edf80a commit 219c537
Showing 1 changed file with 57 additions and 3 deletions.
60 changes: 57 additions & 3 deletions pyobjc-core/Modules/objc/module.m
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,17 @@

static int PyObjC_Initialized = 0;

/*
* free-threaded: No lock needed becausethis value is set once
* during module init.
*/
PyObject* _Nullable PyObjCClass_DefaultModule;

PyObject* _Nullable PyObjC_TypeStr2CFTypeID;

#if Py_GIL_DISABLED
static PyMutex global_release_pool_lock = { 0 };
#endif
static NSAutoreleasePool* _Nullable global_release_pool;

/* Calculate the current version of macOS in a format that
Expand All @@ -46,6 +53,10 @@
} NSOperatingSystemVersion;
#endif

/*
* free-threaded: No lock needed becausethis value is set once
* during module init.
*/
static NSOperatingSystemVersion gSystemVersion = {0, 0, 0};

/*
Expand Down Expand Up @@ -117,14 +128,21 @@ + (void)targetForBecomingMultiThreaded:(id)sender;
@implementation OC_NSAutoreleasePoolCollector
+ (void)newAutoreleasePool
{
/* This method must be called with the mutex locked */
OC_NSAutoreleasePoolCollector* value = [[self alloc] init];
global_release_pool = [[NSAutoreleasePool alloc] init];
(void)[value autorelease];
}

- (void)dealloc
{
#if Py_GIL_DISABLED
PyMutex_Lock(&global_release_pool_lock);
#endif
global_release_pool = nil;
#if Py_GIL_DISABLED
PyMutex_Unlock(&global_release_pool_lock);
#endif
[super dealloc];
}

Expand Down Expand Up @@ -322,7 +340,14 @@ + (void)targetForBecomingMultiThreaded:(id)sender
static PyObject*
have_autorelease_pool(PyObject* self __attribute__((__unused__)))
{
if (global_release_pool) {
#if Py_GIL_DISABLED
PyMutex_Lock(&global_release_pool_lock);
#endif
bool have_pool = (global_release_pool != nil);
#if Py_GIL_DISABLED
PyMutex_Unlock(&global_release_pool_lock);
#endif
if (have_pool) {
Py_RETURN_TRUE;
} else {
Py_RETURN_FALSE;
Expand All @@ -344,8 +369,14 @@ + (void)targetForBecomingMultiThreaded:(id)sender
/* Unconditionally clear the global autorelease pool,
* there's not much we can do if releasing raises.
*/
#if Py_GIL_DISABLED
PyMutex_Lock(&global_release_pool_lock);
#endif
pool = global_release_pool;
global_release_pool = nil;
#if Py_GIL_DISABLED
PyMutex_Unlock(&global_release_pool_lock);
#endif
[pool release];

} @catch (NSObject* localException) {
Expand All @@ -368,6 +399,9 @@ + (void)targetForBecomingMultiThreaded:(id)sender
__attribute__((__unused__)))
{
NSAutoreleasePool* pool;
#if Py_GIL_DISABLED
PyMutex_Lock(&global_release_pool_lock);
#endif
Py_BEGIN_ALLOW_THREADS
@try {
/* Unconditionally set global_release_pool to nil
Expand All @@ -387,6 +421,9 @@ + (void)targetForBecomingMultiThreaded:(id)sender
*/
[OC_NSAutoreleasePoolCollector newAutoreleasePool];
Py_END_ALLOW_THREADS
#if Py_GIL_DISABLED
PyMutex_Unlock(&global_release_pool_lock);
#endif

if (PyErr_Occurred())
return NULL;
Expand Down Expand Up @@ -1685,10 +1722,21 @@ + (void)targetForBecomingMultiThreaded:(id)sender
{
static bool (*contains_func)(const char*) = NULL;
static bool resolved_func = 0;
#if Py_GIL_DISABLED
static PyMutex resolve_lock = { 0 };
#endif

if (!resolved_func) {
contains_func = dlsym(RTLD_DEFAULT, "_dyld_shared_cache_contains_path");
resolved_func = 1;
#if Py_GIL_DISABLED
PyMutex_Lock(&resolve_lock);
if (!resolved_func) {
#endif
contains_func = dlsym(RTLD_DEFAULT, "_dyld_shared_cache_contains_path");
resolved_func = 1;
#if Py_GIL_DISABLED
}
PyMutex_Unlock(&resolve_lock);
#endif
}

if (!PyUnicode_Check(object)) { // LCOV_BR_EXCL_LINE
Expand Down Expand Up @@ -2290,8 +2338,14 @@ static int mod_exec_module(PyObject* m)
/* Allocate an auto-release pool for our own use, this avoids numerous
* warnings during startup of a python script.
*/
#if Py_GIL_DISABLED
PyMutex_Lock(&global_release_pool_lock);
#endif
global_release_pool = nil;
[OC_NSAutoreleasePoolCollector newAutoreleasePool];
#if Py_GIL_DISABLED
PyMutex_Unlock(&global_release_pool_lock);
#endif

/*
* Archives created with Python 2.x can contain instances of
Expand Down

0 comments on commit 219c537

Please sign in to comment.