How to figure out what is being mutated [and cause...
# multiplatform
a
How to figure out what is being mutated [and causes an exception] during coroutine call, invoked from iOS code? The code is already as simple as that:
Copy code
override fun fetch() {
        println("Fetch:start: Running in ${currentThreadName()} ")
        println("Fetch:start: Frozen? -> ${this.isFrozen()} ")
        launch(Dispatchers.Unconfined) {
            println("Fetch:launch: Running in ${currentThreadName()} ") 
         }
       }
Exception is in discussion thread ...
Copy code
at 4   SharedFramework                     0x000000010d2506c2 MutationCheck + 50
        at 5   SharedFramework                     0x000000010d035f63 kfun:kotlinx.atomicfu.AtomicRef.<set-value>(#GENERIC) + 67 (/opt/teamcity-agent/work/88b0986a7186d029/atomicfu/src/nativeMain/kotlin/kotlinx/atomicfu/AtomicFU.kt:17:19)
        at 6   SharedFramework                     0x000000010d034e22 kfun:kotlinx.atomicfu.AtomicRef.compareAndSet(#GENERIC;#GENERIC)ValueType + 114 (/opt/teamcity-agent/work/88b0986a7186d029/atomicfu/src/nativeMain/kotlin/kotlinx/atomicfu/AtomicFU.kt:<unknown>)
        at 7   SharedFramework                     0x000000010d047a42 kfun:kotlinx.coroutines.JobSupport.invokeOnCompletion(kotlin.Boolean;kotlin.Boolean;kotlin.Function1<kotlin.Throwable?,kotlin.Unit>)kotlinx.coroutines.DisposableHandle + 962 (/opt/teamcity-agent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/JobSupport.kt:418:36)
        at 8   SharedFramework                     0x000000010d045095 kfun:kotlinx.coroutines.Job.invokeOnCompletion$default(kotlin.Boolean;kotlin.Boolean;kotlin.Function1<kotlin.Throwable?,kotlin.Unit>;kotlin.Int)kotlinx.coroutines.DisposableHandle + 197 (/opt/teamcity-agent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/Job.kt:323:12)
        at 9   SharedFramework                     0x000000010d047eef kfun:kotlinx.coroutines.JobSupport.attachChild(kotlinx.coroutines.ChildJob)kotlinx.coroutines.ChildHandle + 143 (/opt/teamcity-agent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/JobSupport.kt:880:16)
        at 10  SharedFramework                     0x000000010d12d9c3 kfun:kotlinx.coroutines.JobSupport.initParentJobInternal$kotlinx-coroutines-core(kotlinx.coroutines.Job?) + 195 (/opt/teamcity-agent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/JobSupport.kt:<unknown>)
        at 11  SharedFramework                     0x000000010d192b5b kfun:kotlinx.coroutines.AbstractCoroutine.initParentJob$kotlinx-coroutines-core() + 187 (/opt/teamcity-agent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/AbstractCoroutine.kt:<unknown>)
        at 12  SharedFramework                     0x000000010d191bc9 kfun:kotlinx.coroutines.AbstractCoroutine.start(kotlinx.coroutines.CoroutineStart;#GENERIC;kotlin.coroutines.SuspendFunction1<#GENERIC,#GENERIC>)Generic + 89 (/opt/teamcity-agent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/AbstractCoroutine.kt:154:32)
        at 13  SharedFramework                     0x000000010d1917b0 kfun:kotlinx.coroutines.launch@kotlinx.coroutines.CoroutineScope.(kotlin.coroutines.CoroutineContext;kotlinx.coroutines.CoroutineStart;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,kotlin.Unit>)kotlinx.coroutines.Job + 240 (/opt/teamcity-agent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/Builders.common.kt:55:12)
        at 14  SharedFramework                     0x000000010d1915b2 kfun:kotlinx.coroutines.launch$default@kotlinx.coroutines.CoroutineScope.(kotlin.coroutines.CoroutineContext;kotlinx.coroutines.CoroutineStart;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,kotlin.Unit>;kotlin.Int)kotlinx.coroutines.Job + 290 (/opt/teamcity-agent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/Builders.common.kt:45:8)
        at 15  SharedFramework                     0x000000010d1c54df kfun:com.heureka.shared.sources.KPIDataSource.fetch()
r
- Everything inside an
object
(or inside something that is inside an
object
) is frozen - AtomicFU doesn’t work for me on iOS, I used
kotlin.native.concurrent.AtomicReference
instead - Storing an atomic reference inside an
object
will still freeze the instance referenced, the only gain you have is being able to replace that reference
(Note that everything I said may be unrelated to your problem, but it’s all the immutability problems I encountered)
a
I digged into Coroutine sources and see that an atomic state inside the JobSupport class is modified during invokation.
e
AromicFu on native is not supported yet. It is only a shim to support single-threaded coroutines (many concurrent things, but in the same thread).
a
I was actually using frozenCopyOnWriteList<> from `Stately`to achieve global shared list in Kotlin MPP, but the implementation [probably quite righteously] freezes the list items, but, since items are
CoroutineScope
based, I cannot use coroutines any more, since they modify the object. 😕 😕
Is it possible & not a bad style to use a local (vs class implementation) CoroutineScope object?