Stately icon indicating copy to clipboard operation
Stately copied to clipboard

Nested iso collections cannot be created from the state runner thread (causes deadlock)

Open alusch opened this issue 3 years ago • 2 comments

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:

  1. IsoMutableMap constructor calls createState
  2. That function isn't aware of the StateHolder so it just directly calls runner.stateRun, not realizing we're already on the thread it wants to run on
  3. Work gets enqueued to run on the current thread later
  4. 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.

alusch avatar Nov 12 '21 17:11 alusch

You might be able to work around by manually passing separate StateRunners

russhwolf avatar Nov 12 '21 18:11 russhwolf

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

kpgalligan avatar Nov 12 '21 18:11 kpgalligan