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
173181pthread_key_t terminationKey;
174182pthread_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
184198static 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
195210NO_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
200219static pthread_key_t dummyKey;
201220#endif
221+
222+ #ifndef KONAN_IOS
202223static 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
215237void 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