Skip to content

Commit c09d381

Browse files
authored
[iOS] Generate unique class name for MonoDeadLetter (#89956)
In library mode, it is possible to have multiple shared libraries (runtimes) loaded in the same process. On iOS, we have a small bit of objc to make sure we know when threads die so we can properly detach the runtime. Unfortunately, the class name we use is not unique and results in a crash when calling into a 2nd library. This change makes the class name partially unique to avoid such a circumstance.
1 parent 9666832 commit c09d381

File tree

2 files changed

+12
-16
lines changed

2 files changed

+12
-16
lines changed

src/mono/mono/utils/mono-threads-mach-helper.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,13 @@ mono_threads_init_dead_letter (void)
122122
setObjectForKey = sel_registerName ("setObject:forKey:");
123123
objectForKey = sel_registerName ("objectForKey:");
124124

125-
// define the dead letter class
126-
mono_dead_letter_class = objc_allocateClassPair (nsobject, "MonoDeadLetter", 0);
125+
char *class_name = g_strdup_printf ("MonoDeadLetter%p", &"MonoDeadLetter");
126+
127+
// Define the dead letter class
128+
// The class name needs to be unique in the event different runtimes are loaded into the same process.
129+
mono_dead_letter_class = objc_allocateClassPair (nsobject, class_name, 0);
130+
g_free (class_name);
131+
127132
class_addMethod (mono_dead_letter_class, dealloc, (IMP)mono_dead_letter_dealloc, "v@:");
128133
objc_registerClassPair (mono_dead_letter_class);
129134

src/native/libs/System.Native/pal_autoreleasepool.m

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,7 @@
33

44
#include "pal_autoreleasepool.h"
55
#include <Foundation/Foundation.h>
6-
7-
@interface PlaceholderObject : NSObject
8-
- (void)noop:(id)_;
9-
@end
10-
11-
@implementation PlaceholderObject : NSObject
12-
- (void)noop:(id)_
13-
{
14-
[self release];
15-
}
16-
@end
6+
#include <objc/runtime.h>
177

188
void EnsureNSThreadIsMultiThreaded(void)
199
{
@@ -22,12 +12,13 @@ void EnsureNSThreadIsMultiThreaded(void)
2212
// Start another no-op thread with the NSThread APIs to get NSThread into multithreaded mode.
2313
// The NSAutoReleasePool APIs can't be used on secondary threads until NSThread is in multithreaded mode.
2414
// See https://developer.apple.com/documentation/foundation/nsautoreleasepool for more information.
25-
PlaceholderObject* placeholderObject = [[PlaceholderObject alloc] init];
26-
15+
//
2716
// We need to use detachNewThreadSelector to put NSThread into multithreaded mode.
2817
// We can't use detachNewThreadWithBlock since it doesn't change NSThread into multithreaded mode for some reason.
2918
// See https://developer.apple.com/documentation/foundation/nswillbecomemultithreadednotification for more information.
30-
[NSThread detachNewThreadSelector:@selector(noop:) toTarget:placeholderObject withObject:nil];
19+
id placeholderObject = [[NSMutableString alloc] init];
20+
[NSThread detachNewThreadSelector:@selector(appendString:) toTarget:placeholderObject withObject:@""];
21+
[placeholderObject release];
3122
}
3223
assert([NSThread isMultiThreaded]);
3324
}

0 commit comments

Comments
 (0)