Extract Kotlin_shutdownRuntime (#4497)
This commit is contained in:
committed by
Stanislav Erokhin
parent
3e92699962
commit
91186b4145
@@ -236,7 +236,7 @@ void GC_UnregisterWorker(void* worker) RUNTIME_NOTHROW;
|
||||
void GC_CollectorCallback(void* worker) RUNTIME_NOTHROW;
|
||||
|
||||
bool Kotlin_Any_isShareable(ObjHeader* thiz);
|
||||
void PerformFullGC() RUNTIME_NOTHROW;
|
||||
void PerformFullGC(MemoryState* memory) RUNTIME_NOTHROW;
|
||||
|
||||
bool TryAddHeapRef(const ObjHeader* object);
|
||||
|
||||
|
||||
@@ -76,12 +76,23 @@ inline bool isValidRuntime() {
|
||||
|
||||
volatile int aliveRuntimesCount = 0;
|
||||
|
||||
enum GlobalRuntimeStatus {
|
||||
kGlobalRuntimeUninitialized = 0,
|
||||
kGlobalRuntimeRunning,
|
||||
kGlobalRuntimeShutdown,
|
||||
};
|
||||
|
||||
volatile GlobalRuntimeStatus globalRuntimeStatus = kGlobalRuntimeUninitialized;
|
||||
|
||||
RuntimeState* initRuntime() {
|
||||
SetKonanTerminateHandler();
|
||||
RuntimeState* result = konanConstructInstance<RuntimeState>();
|
||||
if (!result) return kInvalidRuntime;
|
||||
RuntimeCheck(!isValidRuntime(), "No active runtimes allowed");
|
||||
::runtimeState = result;
|
||||
|
||||
compareAndSwap(&globalRuntimeStatus, kGlobalRuntimeUninitialized, kGlobalRuntimeRunning);
|
||||
|
||||
result->memoryState = InitMemory();
|
||||
result->worker = WorkerInit(true);
|
||||
bool firstRuntime = atomicAdd(&aliveRuntimesCount, 1) == 1;
|
||||
@@ -149,6 +160,34 @@ void Kotlin_deinitRuntimeIfNeeded() {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Consider exporting it to interop API.
|
||||
void Kotlin_shutdownRuntime() {
|
||||
// TODO: If checkers are disabled, we can set status to "shutdown" here, and return.
|
||||
auto* runtime = ::runtimeState;
|
||||
RuntimeAssert(runtime != kInvalidRuntime, "Current thread must have Kotlin runtime initialized on it");
|
||||
|
||||
if (Kotlin_cleanersLeakCheckerEnabled()) {
|
||||
// Make sure to collect any lingering cleaners.
|
||||
PerformFullGC(runtime->memoryState);
|
||||
}
|
||||
|
||||
// Stop cleaner worker. Only execute the cleaners if checker is enabled.
|
||||
ShutdownCleaners(Kotlin_cleanersLeakCheckerEnabled());
|
||||
|
||||
// Cleaners are now done, disallow new runtimes.
|
||||
auto lastStatus = compareAndSwap(&globalRuntimeStatus, kGlobalRuntimeRunning, kGlobalRuntimeShutdown);
|
||||
RuntimeAssert(lastStatus == kGlobalRuntimeRunning, "Invalid runtime status for shutdown");
|
||||
|
||||
// TODO: If we add early return at the top, this if would be unneeded.
|
||||
if (Kotlin_memoryLeakCheckerEnabled() || Kotlin_cleanersLeakCheckerEnabled()) {
|
||||
// First make sure workers are gone.
|
||||
WaitNativeWorkersTermination();
|
||||
}
|
||||
|
||||
deinitRuntime(runtime);
|
||||
::runtimeState = kInvalidRuntime;
|
||||
}
|
||||
|
||||
KInt Konan_Platform_canAccessUnaligned() {
|
||||
#if KONAN_NO_UNALIGNED_ACCESS
|
||||
return 0;
|
||||
|
||||
@@ -28,6 +28,12 @@ extern "C" {
|
||||
void Kotlin_initRuntimeIfNeeded();
|
||||
void Kotlin_deinitRuntimeIfNeeded();
|
||||
|
||||
// Can only be called once.
|
||||
// No new runtimes can be initialized on any thread after this.
|
||||
// Must be called on a thread with active runtime.
|
||||
// Using already initialized runtimes on any thread after this is undefined behaviour.
|
||||
void Kotlin_shutdownRuntime();
|
||||
|
||||
// Appends given node to an initializer list.
|
||||
void AppendToInitializersTail(struct InitNode*);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user