Restore runtimeState value in deinitRuntime (#4587)
This commit is contained in:
committed by
Stanislav Erokhin
parent
639029f47e
commit
c582612bd7
@@ -3813,6 +3813,10 @@ if (PlatformInfo.isAppleTarget(project)) {
|
|||||||
createInterop("objcKt43517") {
|
createInterop("objcKt43517") {
|
||||||
it.defFile 'framework/kt43517/kt43517.def'
|
it.defFile 'framework/kt43517/kt43517.def'
|
||||||
}
|
}
|
||||||
|
createInterop("objc_kt42172") {
|
||||||
|
it.defFile 'interop/objc/kt42172/objclib.def'
|
||||||
|
it.headers "$projectDir/interop/objc/kt42172/objclib.h"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
createInterop("withSpaces") {
|
createInterop("withSpaces") {
|
||||||
@@ -4281,6 +4285,25 @@ if (PlatformInfo.isAppleTarget(project)) {
|
|||||||
it.contains("isObjectAliveShouldCrash") // And should contain stack trace.
|
it.contains("isObjectAliveShouldCrash") // And should contain stack trace.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interopTest("interop_objc_kt42172") {
|
||||||
|
source = "interop/objc/kt42172/main.kt"
|
||||||
|
interop = "objc_kt42172"
|
||||||
|
flags = ['-Xopt-in=kotlin.native.internal.InternalForKotlinNative']
|
||||||
|
goldValue = 'Executed finalizer\n'
|
||||||
|
|
||||||
|
doBeforeBuild {
|
||||||
|
mkdir(buildDir)
|
||||||
|
execKonanClang(project.target) {
|
||||||
|
args "$projectDir/interop/objc/kt42172/objclib.m"
|
||||||
|
args "-lobjc", '-fobjc-arc'
|
||||||
|
args '-fPIC', '-shared', '-o', "$buildDir/libobjc_kt42172.dylib"
|
||||||
|
}
|
||||||
|
if (project.target instanceof KonanTarget.IOS_X64) {
|
||||||
|
UtilsKt.codesign(project, "$buildDir/libobjc_kt42172.dylib")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
standaloneTest("jsinterop_math") {
|
standaloneTest("jsinterop_math") {
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import objclib.*
|
||||||
|
import kotlin.native.concurrent.*
|
||||||
|
import kotlinx.cinterop.*
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
val worker = Worker.start()
|
||||||
|
worker.execute(TransferMode.SAFE, {}) {
|
||||||
|
val withFinalizer = WithFinalizer()
|
||||||
|
val finalizer: Finalizer = staticCFunction { ptr: COpaquePointer? ->
|
||||||
|
ptr?.asStableRef<Any>()?.dispose()
|
||||||
|
println("Executed finalizer")
|
||||||
|
}
|
||||||
|
val arg = StableRef.create(Any()).asCPointer()
|
||||||
|
withFinalizer.setFinalizer(finalizer, arg)
|
||||||
|
}.result
|
||||||
|
worker.requestTermination().result
|
||||||
|
waitWorkerTermination(worker)
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
language = Objective-C
|
||||||
|
headerFilter = **/objclib.h
|
||||||
|
linkerOpts = -lobjc_kt42172
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#import <objc/NSObject.h>
|
||||||
|
|
||||||
|
typedef void (*Finalizer)(void*);
|
||||||
|
|
||||||
|
@interface WithFinalizer : NSObject
|
||||||
|
|
||||||
|
- (void)setFinalizer:(Finalizer)finalizer arg:(void*)arg;
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#include "objclib.h"
|
||||||
|
|
||||||
|
@implementation WithFinalizer {
|
||||||
|
Finalizer finalizer_;
|
||||||
|
void* arg_;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dealloc {
|
||||||
|
if (finalizer_) {
|
||||||
|
finalizer_(arg_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setFinalizer:(Finalizer)finalizer arg:(void*)arg {
|
||||||
|
finalizer_ = finalizer;
|
||||||
|
arg_ = arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -140,7 +140,9 @@ RuntimeState* initRuntime() {
|
|||||||
void deinitRuntime(RuntimeState* state, bool destroyRuntime) {
|
void deinitRuntime(RuntimeState* state, bool destroyRuntime) {
|
||||||
RuntimeAssert(state->status == RuntimeStatus::kRunning, "Runtime must be in the running state");
|
RuntimeAssert(state->status == RuntimeStatus::kRunning, "Runtime must be in the running state");
|
||||||
state->status = RuntimeStatus::kDestroying;
|
state->status = RuntimeStatus::kDestroying;
|
||||||
// This may be called after TLS is zeroed out, so ::memoryState in Memory cannot be trusted.
|
// This may be called after TLS is zeroed out, so ::runtimeState and ::memoryState in Memory cannot be trusted.
|
||||||
|
// TODO: This may in fact reallocate TLS without guarantees that it'll be deallocated again.
|
||||||
|
::runtimeState = state;
|
||||||
RestoreMemory(state->memoryState);
|
RestoreMemory(state->memoryState);
|
||||||
bool lastRuntime = atomicAdd(&aliveRuntimesCount, -1) == 0;
|
bool lastRuntime = atomicAdd(&aliveRuntimesCount, -1) == 0;
|
||||||
switch (Kotlin_getDestroyRuntimeMode()) {
|
switch (Kotlin_getDestroyRuntimeMode()) {
|
||||||
@@ -159,6 +161,7 @@ void deinitRuntime(RuntimeState* state, bool destroyRuntime) {
|
|||||||
DeinitMemory(state->memoryState, destroyRuntime);
|
DeinitMemory(state->memoryState, destroyRuntime);
|
||||||
konanDestructInstance(state);
|
konanDestructInstance(state);
|
||||||
WorkerDestroyThreadDataIfNeeded(workerId);
|
WorkerDestroyThreadDataIfNeeded(workerId);
|
||||||
|
::runtimeState = kInvalidRuntime;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Kotlin_deinitRuntimeCallback(void* argument) {
|
void Kotlin_deinitRuntimeCallback(void* argument) {
|
||||||
@@ -191,7 +194,6 @@ void Kotlin_initRuntimeIfNeeded() {
|
|||||||
void Kotlin_deinitRuntimeIfNeeded() {
|
void Kotlin_deinitRuntimeIfNeeded() {
|
||||||
if (isValidRuntime()) {
|
if (isValidRuntime()) {
|
||||||
deinitRuntime(::runtimeState, false);
|
deinitRuntime(::runtimeState, false);
|
||||||
::runtimeState = kInvalidRuntime;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,7 +251,6 @@ void Kotlin_shutdownRuntime() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deinitRuntime(runtime, canDestroyRuntime);
|
deinitRuntime(runtime, canDestroyRuntime);
|
||||||
::runtimeState = kInvalidRuntime;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
KInt Konan_Platform_canAccessUnaligned() {
|
KInt Konan_Platform_canAccessUnaligned() {
|
||||||
|
|||||||
Reference in New Issue
Block a user