From 48bd38542a33f70996046ef3b05238520e9800d1 Mon Sep 17 00:00:00 2001 From: Nikolay Igotti Date: Thu, 14 Jun 2018 11:33:03 +0300 Subject: [PATCH] Frozen global object example. (#1686) --- samples/globalState/src/main/c_interop/global.def | 1 + samples/globalState/src/main/kotlin/Global.kt | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/samples/globalState/src/main/c_interop/global.def b/samples/globalState/src/main/c_interop/global.def index 5904d96df09..022a999c0de 100644 --- a/samples/globalState/src/main/c_interop/global.def +++ b/samples/globalState/src/main/c_interop/global.def @@ -6,6 +6,7 @@ typedef struct { float f; char* string; void* kotlinObject; + void* frozenKotlinObject; } SharedData; SharedData sharedData; diff --git a/samples/globalState/src/main/kotlin/Global.kt b/samples/globalState/src/main/kotlin/Global.kt index 8e166dbbce5..0917244dd67 100644 --- a/samples/globalState/src/main/kotlin/Global.kt +++ b/samples/globalState/src/main/kotlin/Global.kt @@ -17,6 +17,7 @@ import global.* import kotlinx.cinterop.* import platform.posix.* +import konan.worker.* inline fun Int.ensureUnixCallResult(op: String, predicate: (Int) -> Boolean = { x -> x == 0} ): Int { if (!predicate(this)) { @@ -29,6 +30,10 @@ data class SharedDataMember(val double: Double) data class SharedData(val string: String, val int: Int, val member: SharedDataMember) +// Here we access the same shared frozen Kotlin object from multiple threads. +val globalObject: SharedData? + get() = sharedData.frozenKotlinObject?.asStableRef()?.get() + fun dumpShared(prefix: String): Unit { println(""" $prefix: ${pthread_self()} x=${sharedData.x} f=${sharedData.f} s=${sharedData.string!!.toKString()} @@ -43,10 +48,15 @@ fun main(args: Array) { sharedData.x = 239 sharedData.f = 0.5f sharedData.string = "Hello Kotlin!".cstr.getPointer(arena) + // Here we create detached mutable object, which could be later reattached by another thread. sharedData.kotlinObject = konan.worker.detachObjectGraph { SharedData("A string", 42, SharedDataMember(2.39)) } + // Here we create shared frozen object reference, + val stableRef = StableRef.create(SharedData("Shared", 239, SharedDataMember(2.71)).freeze()) + sharedData.frozenKotlinObject = stableRef.asCPointer() dumpShared("thread1") + println("frozen is $globalObject") // Start a new thread, that sees the variable. // memScoped is needed to pass thread's local address to pthread_create(). @@ -58,7 +68,7 @@ fun main(args: Array) { dumpShared("thread2") val kotlinObject = konan.worker.attachObjectGraph(sharedData.kotlinObject) val arg = konan.worker.attachObjectGraph(argC) - println("thread arg is $arg Kotlin object is $kotlinObject") + println("thread arg is $arg Kotlin object is $kotlinObject frozen is $globalObject") // Workaround for compiler issue. null as COpaquePointer? }, konan.worker.detachObjectGraph { SharedDataMember(3.14)} ).ensureUnixCallResult("pthread_create") @@ -68,5 +78,6 @@ fun main(args: Array) { // At this moment we do not need data stored in shared data, so clean up the data // and free memory. sharedData.string = null + stableRef.dispose() arena.clear() }