Skip to content

Commit 3dc5c7c

Browse files
author
yuencong
committed
Fix: Prevent reallocation of TLS during thread exit on iOS
1 parent 060a237 commit 3dc5c7c

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

kotlin-native/runtime/src/main/cpp/Porting.cpp

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@
1818
#ifdef KONAN_ANDROID
1919
#include <android/log.h>
2020
#endif
21+
22+
#ifdef KONAN_IOS
23+
#include <mach-o/dyld.h>
24+
#endif
25+
2126
#include <cstdio>
2227
#include <cstdlib>
2328
#include <stdarg.h>
@@ -170,6 +175,9 @@ void consoleFlush() {
170175
::fflush(stderr);
171176
}
172177

178+
#ifdef KONAN_IOS
179+
THREAD_LOCAL_VARIABLE bool isOnThreadExitSet = false;
180+
#else
173181
pthread_key_t terminationKey;
174182
pthread_once_t terminationKeyOnceControl = PTHREAD_ONCE_INIT;
175183

@@ -180,7 +188,13 @@ struct DestructorRecord {
180188
destructor_t destructor;
181189
void* destructorParameter;
182190
};
191+
#endif
183192

193+
#ifdef KONAN_IOS
194+
static void onThreadExitCallback(void* value) {
195+
isOnThreadExitSet = false;
196+
}
197+
#else
184198
static void onThreadExitCallback(void* value) {
185199
DestructorRecord* record = reinterpret_cast<DestructorRecord*>(value);
186200
pthread_setspecific(terminationKey, nullptr);
@@ -191,14 +205,21 @@ static void onThreadExitCallback(void* value) {
191205
record = next;
192206
}
193207
}
208+
#endif
194209

195210
NO_EXTERNAL_CALLS_CHECK bool isOnThreadExitNotSetOrAlreadyStarted() {
196-
return terminationKey != 0 && pthread_getspecific(terminationKey) == nullptr;
211+
#ifdef KONAN_IOS
212+
return isOnThreadExitSet;
213+
#else
214+
return terminationKey != 0 && pthread_getspecific(terminationKey) == nullptr;
215+
#endif
197216
}
198217

199218
#if KONAN_LINUX
200219
static pthread_key_t dummyKey;
201220
#endif
221+
222+
#ifndef KONAN_IOS
202223
static void onThreadExitInit() {
203224
#if KONAN_LINUX
204225
// Due to glibc bug we have to create first key as dummy, to avoid
@@ -211,8 +232,16 @@ static void onThreadExitInit() {
211232
#endif
212233
pthread_key_create(&terminationKey, onThreadExitCallback);
213234
}
235+
#endif
214236

215237
void onThreadExit(void (*destructor)(void*), void* destructorParameter) {
238+
#ifdef KONAN_IOS
239+
if (!isOnThreadExitSet) {
240+
isOnThreadExitSet = true;
241+
_tlv_atexit(onThreadExitCallback, nullptr);
242+
}
243+
_tlv_atexit(destructor, destructorParameter);
244+
#else
216245
// We cannot use pthread_cleanup_push() as it is lexical scope bound.
217246
pthread_once(&terminationKeyOnceControl, onThreadExitInit);
218247
DestructorRecord* destructorRecord = (DestructorRecord*)std::calloc(1, sizeof(DestructorRecord));
@@ -221,6 +250,7 @@ void onThreadExit(void (*destructor)(void*), void* destructorParameter) {
221250
destructorRecord->next =
222251
reinterpret_cast<DestructorRecord*>(pthread_getspecific(terminationKey));
223252
pthread_setspecific(terminationKey, destructorRecord);
253+
#endif
224254
}
225255

226256
#if KONAN_LINUX

0 commit comments

Comments
 (0)