Piasy
05/28/2020, 12:10 AMWorker
API on native platforms (iOS and Linux), and since Worker
need all the referenced objects to be frozen, so all my states are stored in HashMap
+ AtomicReference
, and whenever I need to update state, I make a deep copy of the HashMap, then modify it, then call state.compareAndSet(state.value, newState)
to update state.
It appears to work fine at first, which is about half year ago, but abortions about runtime assert: Must be newly frozen
in runtime/src/main/cpp/Memory.cpp
happen randomly when I test it more recently. I tried Kotlin 1.3.61 and 1.4-M1, it happened on both version.
Here is my Worker
and state code:
actual class WorkerTaskQueue<T> actual constructor(state: T) {
private val worker = Worker.start()
private val state = AtomicReference(state.freeze())
actual fun state(): T = state.value
actual fun updateState(newState: T): T {
newState.freeze()
while (!state.compareAndSet(state.value, newState)) {
}
return state.value
}
actual fun execute(task: () -> Unit) {
worker.executeAfter(0, task.freeze())
}
}
The abortion is caused by newState.freeze()
above.
I tried to simplify my project, or the scenario to reproduce this abortion, but I failed, I can only reproduce it when a iOS client and Linux client join the same meeting on a local test server, so I'm not sure if it's appropriate to provide the full project. But I can provide it if necessary.
Please help me, thanks!kpgalligan
05/28/2020, 1:23 AMwhile (!state.compareAndSet(state.value, newState)) {
}
kpgalligan
05/28/2020, 1:25 AMkpgalligan
05/28/2020, 1:27 AMkpgalligan
05/28/2020, 1:27 AMkpgalligan
05/28/2020, 1:28 AMPiasy
05/28/2020, 3:47 AMkpgalligan
05/28/2020, 4:08 AMupdateState
could look like:
actual fun updateState(newState: T): T {
state.value = newState.freeze()
return state.value
}
kpgalligan
05/28/2020, 4:08 AMcompareAndSet
won’t helpkpgalligan
05/28/2020, 4:10 AMkpgalligan
05/28/2020, 4:13 AMkpgalligan
05/28/2020, 4:14 AMPiasy
05/28/2020, 5:49 AMnewState.freeze()
. So I think remove compareAndSet
couldn't help, right?Piasy
05/29/2020, 12:28 AMWorkerTaskQueue
with IsolateState
, and remove all the freeze call to my state, and call ensureNeverFrozen()
in state init function. The abortion still happens:
/Users/teamcity1/teamcity_work/4d622a065c544371/runtime/src/main/cpp/Memory.cpp:2500: runtime assert: Must be newly frozen
(lldb) bt
* thread #2, stop reason = signal SIGABRT
frame #0: 0x00000001a2d62df0 libsystem_kernel.dylib`__pthread_kill + 8
frame #1: 0x00000001a2c82930 libsystem_pthread.dylib`pthread_kill + 228
frame #2: 0x00000001a2c10ba4 libsystem_c.dylib`abort + 104
frame #3: 0x0000000100fcc634 AvConf`konan::abort() + 12
frame #4: 0x0000000100fc4d74 AvConf`RuntimeAssertFailed(char const*, char const*) + 168
frame #5: 0x0000000100fdbbd0 AvConf`FreezeSubgraph + 16404
frame #6: 0x0000000100ff98cc AvConf`Kotlin_Worker_freezeInternal + 32
* frame #7: 0x0000000100d53764 AvConf`kfun:kotlin.native.concurrent.freeze@T.(<this>=0x000000028111e348){0<kotlin.Any?>}Generic at Freezing.kt:33:5
frame #8: 0x0000000100defe70 AvConf`kfun:co.touchlab.stately.isolate.BackgroundStateRunner.stateRun$lambda-1#internal(it=0x000000028111cfc8) at BackgroundStateRunner.kt:13:26
frame #9: 0x0000000100ff6d8c AvConf`Worker::processQueueElement(bool) + 2220
frame #10: 0x0000000100ff7f1c AvConf`(anonymous namespace)::workerRoutine(void*) + 72
frame #11: 0x00000001a2c818fc libsystem_pthread.dylib`_pthread_start + 168
BTW, I'm using 1.3.71 now.
Is this some race condition inside KN itself?Piasy
05/29/2020, 12:31 AMIsolateState
in two places in my code, the abortion seems not happen in these two places, but I'm not 100% sure...kpgalligan
05/29/2020, 12:32 AMPiasy
05/29/2020, 1:15 AMkpgalligan
05/29/2020, 1:16 AMPiasy
05/29/2020, 1:18 AMPiasy
05/29/2020, 2:56 PMdocs/kn_freeze_abort_debug.md
for setup guide. Thank you so much!Piasy
05/30/2020, 2:41 PMkpgalligan
05/30/2020, 2:54 PMPiasy
05/30/2020, 2:57 PMPiasy
05/30/2020, 2:58 PMPiasy
05/30/2020, 3:01 PMkpgalligan
05/30/2020, 3:07 PMPiasy
05/30/2020, 3:09 PMkpgalligan
05/30/2020, 3:13 PM