Adding query listeners or using the coroutine extension, which uses query listeners, fails on native/iOS.
Kotlin 1.3.40 and the current 1.2.0-SNAPSHOT
The cause seems to be kotlin.native.concurrent.InvalidMutabilityException: mutation attempt of frozen kotlinx.atomicfu.AtomicRef.
kotlinx.coroutines.CoroutinesInternalError: Fatal exception in coroutines machinery for DispatchedContinuation[EventLoopImpl@3bc36878, Continuation @ $<get-collectToFun>$lambda-0COROUTINE$108]. Please read KDoc to 'handleFatalException' method and report this incident to maintainers
Invalid connection: com.apple.coresymbolicationd
at 0 test.kexe 0x00000001097e2269 kfun:kotlin.Error.<init>(kotlin.String?;kotlin.Throwable?)kotlin.Error + 25 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/Exceptions.kt:14:5)
at 1 test.kexe 0x00000001097e1ad9 kfun:kotlinx.coroutines.CoroutinesInternalError.<init>(kotlin.String;kotlin.Throwable)kotlinx.coroutines.CoroutinesInternalError + 25 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/Exceptions.common.kt:26:98)
at 2 test.kexe 0x00000001097e16fe kfun:kotlinx.coroutines.DispatchedTask.handleFatalException$kotlinx-coroutines-core(kotlin.Throwable?;kotlin.Throwable?) + 366 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/Dispatched.kt:<unknown>)
at 3 test.kexe 0x00000001097e291d kfun:kotlinx.coroutines.DispatchedTask.run() + 1245 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/Dispatched.kt:<unknown>)
at 4 test.kexe 0x00000001097e3b83 kfun:kotlinx.coroutines.EventLoopImpl.processNextEvent()kotlin.Long + 323 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/native/src/EventLoop.kt:96:16)
at 5 test.kexe 0x0000000109912235 kfun:kotlinx.coroutines.BlockingCoroutine.joinBlocking#internal + 437 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/native/src/Builders.kt:65:44)
at 6 test.kexe 0x0000000109911fdd kfun:kotlinx.coroutines.runBlocking(kotlin.coroutines.CoroutineContext;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,#GENERIC>)Generic + 893 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/native/src/Builders.kt:50:22)
at 7 test.kexe 0x0000000109911c10 kfun:kotlinx.coroutines.runBlocking$default(kotlin.coroutines.CoroutineContext;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,#GENERIC>;kotlin.Int)Generic + 176 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/native/src/Builders.kt:33:8)
at 8 test.kexe 0x0000000109911ab8 kfun:foo.bar.common.coroutines.runBlocking(kotlin.coroutines.SuspendFunction0<#GENERIC>)Generic + 104 (/foo/bar/common/coroutines/RunBlocking.kt:<unknown>)
at 9 test.kexe 0x00000001099119b1 kfun:foo.bar.common.data.GithubRepositoryDatabaseTest.Table should have 2 entries with coroutines() + 97 (/foo/bar/common/data/GithubRepositoryDatabase.Test.kt:<unknown>)
at 10 test.kexe 0x0000000109911948 kfun:foo.bar.common.data.$GithubRepositoryDatabaseTest$test$0.$Table should have 2 entries with coroutines$FUNCTION_REFERENCE$24.invoke#internal + 24 (/foo/bar/common/data/GithubRepositoryDatabase.Test.kt:119:6)
at 11 test.kexe 0x0000000109911919 kfun:foo.bar.common.data.$GithubRepositoryDatabaseTest$test$0.$Table should have 2 entries with coroutines$FUNCTION_REFERENCE$24.$<bridge-UNNN>invoke(#GENERIC)#internal + 25 (/foo/bar/common/data/GithubRepositoryDatabase.Test.kt:119:6)
at 12 test.kexe 0x000000010990e34d kfun:kotlin.native.internal.test.BaseClassSuite.TestCase.run() + 541 (/Users/teamcity/buildAgent/work/4d622a065c544371/backend.native/build/stdlib/generated/_Collections.kt:97:7)
at 13 test.kexe 0x00000001097f851c kfun:kotlin.native.internal.test.TestRunner.run#internal + 1036 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/native/internal/test/TestRunner.kt:223:0)
at 14 test.kexe 0x00000001097f7a51 kfun:kotlin.native.internal.test.TestRunner.runIteration#internal + 1281 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/system/Timing.kt:33:12)
at 15 test.kexe 0x00000001097f72f0 kfun:kotlin.native.internal.test.TestRunner.run()kotlin.Int + 576 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/native/internal/test/TestRunner.kt:270:0)
at 16 test.kexe 0x00000001097f61e2 kfun:kotlin.native.internal.test.testLauncherEntryPoint(kotlin.Array<kotlin.String>)kotlin.Int + 114 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/native/internal/test/Launcher.kt:19:47)
at 17 test.kexe 0x00000001097f6161 kfun:kotlin.native.internal.test.main(kotlin.Array<kotlin.String>) + 17 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/native/internal/test/Launcher.kt:23:5)
at 18 test.kexe 0x00000001097f60df Konan_start + 63 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/launcher/kotlin/konan/start.kt:<unknown>)
at 19 test.kexe 0x00000001097f5f6e Init_and_run_start + 78
at 20 libdyld.dylib 0x000000010bb0e541 start + 1
at 21 ??? 0x0000000000000001 0x0 + 1
Caused by: kotlin.native.concurrent.InvalidMutabilityException: mutation attempt of frozen kotlinx.atomicfu.AtomicRef@3a5d5f98
at 0 test.kexe 0x00000001097bcd27 kfun:kotlin.Throwable.<init>(kotlin.String?)kotlin.Throwable + 23 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/Throwable.kt:21:56)
at 1 test.kexe 0x00000001097bcce5 kfun:kotlin.Exception.<init>(kotlin.String?)kotlin.Exception + 21 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/Exceptions.kt:23:5)
at 2 test.kexe 0x00000001097bccb5 kfun:kotlin.RuntimeException.<init>(kotlin.String?)kotlin.RuntimeException + 21 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/Exceptions.kt:34:5)
at 3 test.kexe 0x00000001097bdfb5 kfun:kotlin.native.concurrent.InvalidMutabilityException.<init>(kotlin.String)kotlin.native.concurrent.InvalidMutabilityException + 21 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/native/concurrent/Freezing.kt:22:85)
at 4 test.kexe 0x00000001099ad410 ThrowInvalidMutabilityException + 256 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/native/concurrent/Internal.kt:77:11)
at 5 test.kexe 0x00000001099c6612 MutationCheck + 50
at 6 test.kexe 0x00000001097cb25e kfun:kotlinx.atomicfu.AtomicRef.<set-value>(#GENERIC) + 30 (/opt/buildAgent/work/88b0986a7186d029/atomicfu/src/nativeMain/kotlin/kotlinx/atomicfu/AtomicFU.kt:17:19)
at 7 test.kexe 0x00000001097ca8e6 kfun:kotlinx.atomicfu.AtomicRef.compareAndSet(#GENERIC;#GENERIC)kotlin.Boolean + 118 (/opt/buildAgent/work/88b0986a7186d029/atomicfu/src/nativeMain/kotlin/kotlinx/atomicfu/AtomicFU.kt:<unknown>)
at 8 test.kexe 0x00000001097ca25e kfun:kotlinx.coroutines.JobSupport.tryMakeCompletingSlowPath#internal + 462 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/JobSupport.kt:834:21)
at 9 test.kexe 0x00000001097ca02a kfun:kotlinx.coroutines.JobSupport.tryMakeCompleting#internal + 218 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/JobSupport.kt:813:16)
at 10 test.kexe 0x000000010985f295 kfun:kotlinx.coroutines.JobSupport.makeCompletingOnce$kotlinx-coroutines-core(kotlin.Any?;kotlin.Int)kotlin.Boolean + 213 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/JobSupport.kt:789:15)
at 11 test.kexe 0x000000010985f17d kfun:kotlinx.coroutines.AbstractCoroutine.resumeWith(kotlin.Result<#GENERIC>) + 109 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/AbstractCoroutine.kt:<unknown>)
at 12 test.kexe 0x00000001097dddf6 kfun:kotlin.coroutines.native.internal.BaseContinuationImpl.resumeWith(kotlin.Result<kotlin.Any?>) + 646 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/coroutines/ContinuationImpl.kt:<unknown>)
at 13 test.kexe 0x00000001097e28a3 kfun:kotlinx.coroutines.DispatchedTask.run() + 1123 (/Users/teamcity/buildAgent/work/4d622a065c544371/backend.native/build/stdlib/kotlin/util/Result.kt:151:0)
at 14 test.kexe 0x00000001097e3b83 kfun:kotlinx.coroutines.EventLoopImpl.processNextEvent()kotlin.Long + 323 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/native/src/EventLoop.kt:96:16)
at 15 test.kexe 0x0000000109912235 kfun:kotlinx.coroutines.BlockingCoroutine.joinBlocking#internal + 437 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/native/src/Builders.kt:65:44)
at 16 test.kexe 0x0000000109911fdd kfun:kotlinx.coroutines.runBlocking(kotlin.coroutines.CoroutineContext;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,#GENERIC>)Generic + 893 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/native/src/Builders.kt:50:22)
at 17 test.kexe 0x0000000109911c10 kfun:kotlinx.coroutines.runBlocking$default(kotlin.coroutines.CoroutineContext;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,#GENERIC>;kotlin.Int)Generic + 176 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/native/src/Builders.kt:33:8)
at 18 test.kexe 0x0000000109911ab8 kfun:foo.bar.common.coroutines.runBlocking(kotlin.coroutines.SuspendFunction0<#GENERIC>)Generic + 104 (/foo/bar/common/coroutines/RunBlocking.kt:<unknown>)
at 19 test.kexe 0x00000001099119b1 kfun:foo.bar.common.data.GithubRepositoryDatabaseTest.Table should have 2 entries with coroutines() + 97 (/foo/bar/common/data/GithubRepositoryDatabase.Test.kt:<unknown>)
at 20 test.kexe 0x0000000109911948 kfun:foo.bar.common.data.$GithubRepositoryDatabaseTest$test$0.$Table should have 2 entries with coroutines$FUNCTION_REFERENCE$24.invoke#internal + 24 (/foo/bar/common/data/GithubRepositoryDatabase.Test.kt:119:6)
at 21 test.kexe 0x0000000109911919 kfun:foo.bar.common.data.$GithubRepositoryDatabaseTest$test$0.$Table should have 2 entries with coroutines$FUNCTION_REFERENCE$24.$<bridge-UNNN>invoke(#GENERIC)#internal + 25 (/foo/bar/common/data/GithubRepositoryDatabase.Test.kt:119:6)
at 22 test.kexe 0x000000010990e34d kfun:kotlin.native.internal.test.BaseClassSuite.TestCase.run() + 541 (/Users/teamcity/buildAgent/work/4d622a065c544371/backend.native/build/stdlib/generated/_Collections.kt:97:7)
at 23 test.kexe 0x00000001097f851c kfun:kotlin.native.internal.test.TestRunner.run#internal + 1036 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/native/internal/test/TestRunner.kt:223:0)
at 24 test.kexe 0x00000001097f7a51 kfun:kotlin.native.internal.test.TestRunner.runIteration#internal + 1281 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/system/Timing.kt:33:12)
at 25 test.kexe 0x00000001097f72f0 kfun:kotlin.native.internal.test.TestRunner.run()kotlin.Int + 576 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/native/internal/test/TestRunner.kt:270:0)
at 26 test.kexe 0x00000001097f61e2 kfun:kotlin.native.internal.test.testLauncherEntryPoint(kotlin.Array<kotlin.String>)kotlin.Int + 114 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/native/internal/test/Launcher.kt:19:47)
at 27 test.kexe 0x00000001097f6161 kfun:kotlin.native.internal.test.main(kotlin.Array<kotlin.String>) + 17 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/native/internal/test/Launcher.kt:23:5)
at 28 test.kexe 0x00000001097f60df Konan_start + 63 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/launcher/kotlin/konan/start.kt:<unknown>)
kotlin.native.concurrent.InvalidMutabilityException: mutation attempt of frozen kotlinx.coroutines.EventLoopImpl@3bc36878
at 0 test.kexe 0x00000001097bcd27 kfun:kotlin.Throwable.<init>(kotlin.String?)kotlin.Throwable + 23 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/Throwable.kt:21:56)
at 1 test.kexe 0x00000001097bcce5 kfun:kotlin.Exception.<init>(kotlin.String?)kotlin.Exception + 21 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/Exceptions.kt:23:5)
at 2 test.kexe 0x00000001097bccb5 kfun:kotlin.RuntimeException.<init>(kotlin.String?)kotlin.RuntimeException + 21 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/Exceptions.kt:34:5)
at 3 test.kexe 0x00000001097bdfb5 kfun:kotlin.native.concurrent.InvalidMutabilityException.<init>(kotlin.String)kotlin.native.concurrent.InvalidMutabilityException + 21 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/native/concurrent/Freezing.kt:22:85)
at 4 test.kexe 0x00000001099ad410 ThrowInvalidMutabilityException + 256 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/native/concurrent/Internal.kt:77:11)
at 5 test.kexe 0x00000001099c6612 MutationCheck + 50
at 6 test.kexe 0x00000001097e1a9e kfun:kotlinx.coroutines.EventLoop.<set-useCount>#internal + 30 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/EventLoop.common.kt:23:13)
at 7 test.kexe 0x00000001097e180e kfun:kotlinx.coroutines.EventLoop.decrementUseCount(kotlin.Boolean) + 110 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/EventLoop.common.kt:106:13)
at 8 test.kexe 0x000000010991286b kfun:kotlinx.coroutines.EventLoop.decrementUseCount$default(kotlin.Boolean;kotlin.Int) + 43 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/EventLoop.common.kt:112:6)
at 9 test.kexe 0x0000000109912475 kfun:kotlinx.coroutines.BlockingCoroutine.joinBlocking#internal + 1013 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/native/src/Builders.kt:61:9)
at 10 test.kexe 0x0000000109911fdd kfun:kotlinx.coroutines.runBlocking(kotlin.coroutines.CoroutineContext;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,#GENERIC>)Generic + 893 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/native/src/Builders.kt:50:22)
at 11 test.kexe 0x0000000109911c10 kfun:kotlinx.coroutines.runBlocking$default(kotlin.coroutines.CoroutineContext;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,#GENERIC>;kotlin.Int)Generic + 176 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/native/src/Builders.kt:33:8)
at 12 test.kexe 0x0000000109911ab8 kfun:foo.bar.common.coroutines.runBlocking(kotlin.coroutines.SuspendFunction0<#GENERIC>)Generic + 104 (/foo/bar/common/coroutines/RunBlocking.kt:<unknown>)
at 13 test.kexe 0x00000001099119b1 kfun:foo.bar.common.data.GithubRepositoryDatabaseTest.Table should have 2 entries with coroutines() + 97 (/foo/bar/common/data/GithubRepositoryDatabase.Test.kt:<unknown>)
at 14 test.kexe 0x0000000109911948 kfun:foo.bar.common.data.$GithubRepositoryDatabaseTest$test$0.$Table should have 2 entries with coroutines$FUNCTION_REFERENCE$24.invoke#internal + 24 (/foo/bar/common/data/GithubRepositoryDatabase.Test.kt:119:6)
at 15 test.kexe 0x0000000109911919 kfun:foo.bar.common.data.$GithubRepositoryDatabaseTest$test$0.$Table should have 2 entries with coroutines$FUNCTION_REFERENCE$24.$<bridge-UNNN>invoke(#GENERIC)#internal + 25 (/foo/bar/common/data/GithubRepositoryDatabase.Test.kt:119:6)
at 16 test.kexe 0x000000010990e34d kfun:kotlin.native.internal.test.BaseClassSuite.TestCase.run() + 541 (/Users/teamcity/buildAgent/work/4d622a065c544371/backend.native/build/stdlib/generated/_Collections.kt:97:7)
at 17 test.kexe 0x00000001097f851c kfun:kotlin.native.internal.test.TestRunner.run#internal + 1036 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/native/internal/test/TestRunner.kt:223:0)
at 18 test.kexe 0x00000001097f7a51 kfun:kotlin.native.internal.test.TestRunner.runIteration#internal + 1281 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/system/Timing.kt:33:12)
at 19 test.kexe 0x00000001097f72f0 kfun:kotlin.native.internal.test.TestRunner.run()kotlin.Int + 576 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/native/internal/test/TestRunner.kt:270:0)
at 20 test.kexe 0x00000001097f61e2 kfun:kotlin.native.internal.test.testLauncherEntryPoint(kotlin.Array<kotlin.String>)kotlin.Int + 114 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/native/internal/test/Launcher.kt:19:47)
at 21 test.kexe 0x00000001097f6161 kfun:kotlin.native.internal.test.main(kotlin.Array<kotlin.String>) + 17 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/native/internal/test/Launcher.kt:23:5)
at 22 test.kexe 0x00000001097f60df Konan_start + 63 (/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/launcher/kotlin/konan/start.kt:<unknown>)
at 23 test.kexe 0x00000001097f5f6e Init_and_run_start + 78
at 24 libdyld.dylib 0x000000010bb0e541 start + 1
at 25 ??? 0x0000000000000001 0x0 + 1
Any ideas or workarounds?
"Adding query listeners"
Adding a listener on native means it'll freeze the listener you pass in. Listeners in general on native absolutely work, with the caveat that the listener will get frozen when it's passed in (as well as anything it references).
"or using the coroutine extension, which uses query listeners"
I haven't worked on the coroutine extension, but native support should be removed as it won't work properly until there's a multithreaded coroutines implementation for native.
For now, don't attempt to use Flow and native together, unless everything is happening in the same thread (presumably the main one). You can use listeners, but (again) be aware that your listener and everything it touches is frozen.
Live example of multiplatform with a reactive architecture using SqlDelight: https://github.com/touchlab/DroidconKotlin/
Basic pub/sub: https://github.com/touchlab/DroidconKotlin/blob/master/sessionize/lib/src/commonMain/kotlin/co/touchlab/sessionize/db/QueryPub.kt
Experimental example using Badoo's Reaktive: https://github.com/touchlab/DroidconKotlin/blob/kpg/reaktive/sessionize/lib/src/commonMain/kotlin/co/touchlab/sessionize/reaktive/ReaktiveExtensions.kt
Watching the commits to Kotlin/Native proper, there is movement on the basis for MT coroutines, and when that lands a lot of these other frameworks will kind of wither, but for today you need to hand roll things a bit.
Closing. In summary, until Multithreaded coroutines, can't use coroutines or we'd need to refactor how listeners work and (probably) live in the main thread.
As a workaround can we use the ThreadLocalRef here?
The modified logic would look like:
fun <T : Any> Query<T>.asFlow(): Flow<Query<T>> = callbackFlow<Query<T>> {
// using ThreadLocalRef as Query.Listener and all references in it get frozen on native
// May be removed once fixed in SQLDelight https://github.com/square/sqldelight/issues/1390
val onNextRef: ThreadLocalRef<() -> Unit> = ThreadLocalRef()
onNextRef.value = {
offer(this@asFlow)
}
val listener = object : Query.Listener {
override fun queryResultsChanged() {
onNextRef.value?.invoke()
}
}
addListener(listener)
offer(this@asFlow)
awaitClose {
removeListener(listener)
onNextRef.remove()
}
}.conflate()
ThreadLocalRef logic helped .. had to make it actual/expected with this implementation for iOS.
Most helpful comment
As a workaround can we use the ThreadLocalRef here?
https://github.com/square/sqldelight/blob/master/extensions/coroutines-extensions/src/commonMain/kotlin/com/squareup/sqldelight/runtime/coroutines/FlowExtensions.kt#L38
The modified logic would look like: