Nested iso collections cannot be created from the state runner thread (causes deadlock)
We have a bit of fairly complicated logic in our project that uses an IsoMutableMap whose value is another IsoMutableMap, something like
val nested = IsoMutableMap<Int, IsoMutableMap<Int, Int>>()
As part of a recent change, we ended up with some code that boils down to
nested.access {
it[0] = IsoMutableMap()
}
and were surprised to find that this causes a deadlock:
-
IsoMutableMapconstructor callscreateState - That function isn't aware of the
StateHolderso it just directly callsrunner.stateRun, not realizing we're already on the thread it wants to run on - Work gets enqueued to run on the current thread later
- Current thread blocks on that future work - deadlock
Not sure if there's a clean way that the threading information could be conveyed here to do the right thing.
You might be able to work around by manually passing separate StateRunners
I'd need to think about this. We have some internal constructors that let you fork off state. Not on IsoMutableMap, though. You may be able to try something like this:
fun <K, V> IsoMutableMap<K, V>.makeMap(): IsolateState<MutableMap<K, V>> = access { IsolateState(fork(mutableMapOf<K, V>())) }
Then your type would be
val nested = IsoMutableMap<Int, IsolateState<MutableMap<K, V>>>()
There's probably a better way to handle it, but I haven't done a ton of iso state in a while