[K/N] Dispose ObjC objects from main thread on main thread. ^KT-56402
Merge-request: KT-MR-9515 Merged-by: Alexander Shabalin <Alexander.Shabalin@jetbrains.com>
This commit is contained in:
committed by
Space Team
parent
5282e60328
commit
82f94015f1
@@ -30,6 +30,7 @@ RUNTIME_WEAK int32_t Kotlin_printToAndroidLogcat = 1;
|
||||
RUNTIME_WEAK int32_t Kotlin_appStateTracking = 0;
|
||||
RUNTIME_WEAK int32_t Kotlin_mimallocUseDefaultOptions = 1;
|
||||
RUNTIME_WEAK int32_t Kotlin_mimallocUseCompaction = 0;
|
||||
RUNTIME_WEAK int32_t Kotlin_objcDisposeOnMain = 0;
|
||||
|
||||
ALWAYS_INLINE compiler::DestroyRuntimeMode compiler::destroyRuntimeMode() noexcept {
|
||||
return static_cast<compiler::DestroyRuntimeMode>(Kotlin_destroyRuntimeMode);
|
||||
@@ -73,3 +74,7 @@ ALWAYS_INLINE bool compiler::mimallocUseDefaultOptions() noexcept {
|
||||
ALWAYS_INLINE bool compiler::mimallocUseCompaction() noexcept {
|
||||
return Kotlin_mimallocUseCompaction != 0;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE bool compiler::objcDisposeOnMain() noexcept {
|
||||
return Kotlin_objcDisposeOnMain != 0;
|
||||
}
|
||||
|
||||
@@ -115,6 +115,7 @@ AppStateTracking appStateTracking() noexcept;
|
||||
int getSourceInfo(void* addr, SourceInfo *result, int result_size) noexcept;
|
||||
bool mimallocUseDefaultOptions() noexcept;
|
||||
bool mimallocUseCompaction() noexcept;
|
||||
bool objcDisposeOnMain() noexcept;
|
||||
|
||||
#ifdef KONAN_ANDROID
|
||||
bool printToAndroidLogcat() noexcept;
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "MainQueueProcessor.hpp"
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include "KAssert.h"
|
||||
|
||||
#if KONAN_SUPPORTS_GRAND_CENTRAL_DISPATCH
|
||||
#include <dispatch/dispatch.h>
|
||||
#endif
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
namespace {
|
||||
|
||||
#if KONAN_SUPPORTS_GRAND_CENTRAL_DISPATCH
|
||||
std::atomic<bool> isMainQueueProcessed = false;
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
void kotlin::initializeMainQueueProcessor() noexcept {
|
||||
#if KONAN_SUPPORTS_GRAND_CENTRAL_DISPATCH
|
||||
dispatch_async_f(
|
||||
dispatch_get_main_queue(), nullptr, [](void*) { isMainQueueProcessed.store(true, std::memory_order_relaxed); });
|
||||
#endif
|
||||
}
|
||||
|
||||
bool kotlin::isMainQueueProcessorAvailable() noexcept {
|
||||
#if KONAN_SUPPORTS_GRAND_CENTRAL_DISPATCH
|
||||
return isMainQueueProcessed.load(std::memory_order_relaxed);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void kotlin::runOnMainQueue(void* arg, void (*f)(void*)) noexcept {
|
||||
RuntimeAssert(isMainQueueProcessorAvailable(), "Running on main queue when it's not processed");
|
||||
#if KONAN_SUPPORTS_GRAND_CENTRAL_DISPATCH
|
||||
dispatch_async_f(dispatch_get_main_queue(), arg, f);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace kotlin {
|
||||
|
||||
void initializeMainQueueProcessor() noexcept;
|
||||
|
||||
bool isMainQueueProcessorAvailable() noexcept;
|
||||
|
||||
// Run `f(arg)` on main queue without waiting for its completion.
|
||||
// Only valid if `isMainQueueProcessorAvailable()` returns true.
|
||||
void runOnMainQueue(void* arg, void (*f)(void*)) noexcept;
|
||||
|
||||
} // namespace kotlin
|
||||
@@ -108,7 +108,8 @@ ALWAYS_INLINE void send_releaseAsAssociatedObject(void* associatedObject) {
|
||||
|
||||
extern "C" ALWAYS_INLINE void Kotlin_ObjCExport_releaseAssociatedObject(void* associatedObject) {
|
||||
if (associatedObject != nullptr) {
|
||||
kotlin::ThreadStateGuard guard(kotlin::ThreadState::kNative);
|
||||
// May already be in the native state if was scheduled on the main queue.
|
||||
NativeOrUnregisteredThreadGuard guard(/*reentrant=*/ true);
|
||||
send_releaseAsAssociatedObject(associatedObject);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "CompilerConstants.hpp"
|
||||
#include "Exceptions.h"
|
||||
#include "KAssert.h"
|
||||
#include "MainQueueProcessor.hpp"
|
||||
#include "Memory.h"
|
||||
#include "ObjCExportInit.h"
|
||||
#include "ObjectAlloc.hpp"
|
||||
@@ -135,6 +136,9 @@ RuntimeState* initRuntime() {
|
||||
// Keep global variables in state as well.
|
||||
if (firstRuntime) {
|
||||
konan::consoleInit();
|
||||
if (compiler::objcDisposeOnMain()) {
|
||||
kotlin::initializeMainQueueProcessor();
|
||||
}
|
||||
#if KONAN_OBJC_INTEROP
|
||||
Kotlin_ObjCExport_initialize();
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user