[K/N] Deprecated freezing ^KT-50541

Starting with 1.7.20 freezing is deprecated. See https://github.com/JetBrains/kotlin/blob/master/kotlin-native/NEW_MM.md#freezing-deprecation for details.

Merge-request: KT-MR-6399
Merged-by: Alexander Shabalin <Alexander.Shabalin@jetbrains.com>
This commit is contained in:
Alexander Shabalin
2022-06-16 09:04:14 +00:00
committed by Space
parent b482b0e86d
commit 29f3445721
99 changed files with 321 additions and 68 deletions
@@ -20,9 +20,9 @@ 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.
// Here we access the same shared Kotlin object from multiple threads.
val globalObject: SharedData?
get() = sharedData.frozenKotlinObject?.asStableRef<SharedData>()?.get()
get() = sharedData.kotlinObject?.asStableRef<SharedData>()?.get()
fun dumpShared(prefix: String) {
println("""
@@ -39,16 +39,11 @@ fun main() {
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 = DetachedObjectGraph {
SharedData("A string", 42, SharedDataMember(2.39))
}.asCPointer()
// Here we create shared frozen object reference,
val stableRef = StableRef.create(SharedData("Shared", 239, SharedDataMember(2.71)).freeze())
sharedData.frozenKotlinObject = stableRef.asCPointer()
// Here we create shared object reference,
val stableRef = StableRef.create(SharedData("Shared", 239, SharedDataMember(2.71)))
sharedData.kotlinObject = stableRef.asCPointer()
dumpShared("thread1")
println("frozen is $globalObject")
println("shared is $globalObject")
// Start a new thread, that sees the variable.
// memScoped is needed to pass thread's local address to pthread_create().
@@ -57,12 +52,12 @@ fun main() {
pthread_create(thread.ptr, null, staticCFunction { argC ->
initRuntimeIfNeeded()
dumpShared("thread2")
val kotlinObject = DetachedObjectGraph<SharedData>(sharedData.kotlinObject).attach()
val arg = DetachedObjectGraph<SharedDataMember>(argC).attach()
println("thread arg is $arg Kotlin object is $kotlinObject frozen is $globalObject")
val arg = argC!!.asStableRef<SharedDataMember>()
println("thread arg is ${arg.get()} shared is $globalObject")
arg.dispose()
// Workaround for compiler issue.
null as COpaquePointer?
}, DetachedObjectGraph { SharedDataMember(3.14)}.asCPointer() ).ensureUnixCallResult("pthread_create")
}, StableRef.create(SharedDataMember(3.14)).asCPointer() ).ensureUnixCallResult("pthread_create")
pthread_join(thread.value, null).ensureUnixCallResult("pthread_join")
}
@@ -6,7 +6,6 @@ typedef struct {
float f;
char* string;
void* kotlinObject;
void* frozenKotlinObject;
} SharedDataStruct;
SharedDataStruct sharedData;
@@ -1,6 +1,6 @@
package sample.objc
import kotlinx.cinterop.staticCFunction
import kotlinx.cinterop.*
import platform.Foundation.NSOperationQueue
import platform.Foundation.NSThread
import platform.darwin.dispatch_async_f
@@ -10,11 +10,12 @@ import kotlin.native.concurrent.*
import kotlin.test.assertNotNull
inline fun <reified T> executeAsync(queue: NSOperationQueue, crossinline producerConsumer: () -> Pair<T, (T) -> Unit>) {
dispatch_async_f(queue.underlyingQueue, DetachedObjectGraph {
dispatch_async_f(queue.underlyingQueue, StableRef.create(
producerConsumer()
}.asCPointer(), staticCFunction { it ->
val result = DetachedObjectGraph<Pair<T, (T) -> Unit>>(it).attach()
result.second(result.first)
).asCPointer(), staticCFunction { it ->
val result = it!!.asStableRef<Pair<T, (T) -> Unit>>()
result.get().second(result.get().first)
result.dispose()
})
}
@@ -60,8 +61,7 @@ object Continuator {
fun wrap(operation: () -> Unit, after: () -> Unit): () -> Unit {
assert(NSThread.isMainThread())
assert(operation.isFrozen)
val id = Any().freeze()
val id = Any()
map[id] = Pair(0, after)
return {
initRuntimeIfNeeded()
@@ -69,13 +69,12 @@ object Continuator {
executeAsync(NSOperationQueue.mainQueue) {
Pair(id, { id: Any -> Continuator.execute(id) })
}
}.freeze()
}
}
fun <P> wrap(operation: () -> P, block: (P) -> Unit): () -> Unit {
assert(NSThread.isMainThread())
assert(operation.isFrozen)
val id = Any().freeze()
val id = Any()
map[id] = Pair(1, block)
return {
initRuntimeIfNeeded()
@@ -85,7 +84,7 @@ object Continuator {
Continuator.execute(it.first, it.second)
})
}
}.freeze()
}
}
fun execute(id: Any) {
@@ -18,14 +18,8 @@ import kotlin.test.assertNotNull
data class QueryResult(val json: Map<String, *>?, val error: String?)
private fun MutableData.asNSData() = this.withPointerLocked { it, size ->
val result = NSMutableData.create(length = size.convert())!!
memcpy(result.mutableBytes, it, size.convert())
result
}
private fun MutableData.asJSON(): Map<String, *>? =
NSJSONSerialization.JSONObjectWithData(this.asNSData(), 0, null) as? Map<String, *>
private val NSData.json: Map<String, *>?
get() = NSJSONSerialization.JSONObjectWithData(this, 0, null) as? Map<String, *>
fun main() {
autoreleasepool {
@@ -60,7 +54,7 @@ class Controller : NSObject() {
// Here we call continuator service to ensure we can access mutable state from continuation.
dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND.convert(), 0),
Continuator.wrap({ println("In queue ${dispatch_get_current_queue()}")}.freeze()) {
Continuator.wrap({ println("In queue ${dispatch_get_current_queue()}")}) {
println("After in queue ${dispatch_get_current_queue()}: $index")
})
@@ -88,14 +82,10 @@ class Controller : NSObject() {
class HttpDelegate: NSObject(), NSURLSessionDataDelegateProtocol {
private val asyncQueue = NSOperationQueue()
private val receivedData = MutableData()
init {
freeze()
}
private var receivedData: NSData? = null
fun fetchUrl(url: String) {
receivedData.reset()
receivedData = null
val session = NSURLSession.sessionWithConfiguration(
NSURLSessionConfiguration.defaultSessionConfiguration(),
this,
@@ -106,7 +96,7 @@ class Controller : NSObject() {
override fun URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData: NSData) {
initRuntimeIfNeeded()
receivedData.append(didReceiveData.bytes, didReceiveData.length.convert())
receivedData = didReceiveData
}
override fun URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError: NSError?) {
@@ -117,7 +107,7 @@ class Controller : NSObject() {
Pair(when {
response == null -> QueryResult(null, didCompleteWithError?.localizedDescription)
response.statusCode.toInt() != 200 -> QueryResult(null, "${response.statusCode.toInt()})")
else -> QueryResult(receivedData.asJSON(), null)
else -> QueryResult(receivedData?.json, null)
}, { result: QueryResult ->
appDelegate.contentText.string = result.json?.toString() ?: "Error: ${result.error}"
appDelegate.canClick = true