Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 602b41c3 authored by Steve Elliott's avatar Steve Elliott
Browse files

[kairos] finish outputs before ending transaction

Flag: com.android.systemui.status_bar_mobile_icon_kairos
Bug: 383172066
Test: atest
Change-Id: I8289df7d735b747a1f8ee6d35bfe4bc703b55388
parent 9ae9bad4
Loading
Loading
Loading
Loading
+35 −48
Original line number Diff line number Diff line
@@ -34,8 +34,6 @@ import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.isActive
import kotlinx.coroutines.job
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.yield

private val nextNetworkId = AtomicLong()
@@ -78,7 +76,6 @@ internal class Network(
    private val muxMovers = ArrayDeque<MuxDeferredNode<*, *, *>>()
    private val deactivations = ArrayDeque<PushNode<*>>()
    private val outputDeactivations = ArrayDeque<Output<*>>()
    private val transactionMutex = Mutex()
    private val inputScheduleChan = Channel<ScheduledAction<*>>()

    override fun scheduleOutput(output: Output<*>) {
@@ -133,7 +130,6 @@ internal class Network(
                    }
                }
            }
            transactionMutex.withLock {
            val e = epoch
            logDuration(indent = 0, { "Kairos Transaction epoch=$e" }, trace = true) {
                val evalScope =
@@ -148,7 +144,7 @@ internal class Network(
                        }
                    }
                    // Step through the network
                        doTransaction(evalScope)
                    coroutineScope { doTransaction(evalScope, coroutineScope = this) }
                } catch (e: Exception) {
                    // Signal failure
                    while (actions.isNotEmpty()) {
@@ -167,7 +163,6 @@ internal class Network(
            }
        }
    }
    }

    /** Evaluates [block] inside of a new transaction when the network is ready. */
    fun <R> transaction(reason: String, block: EvalScope.() -> R): Deferred<R> =
@@ -189,7 +184,7 @@ internal class Network(
        block().also { deferScopeImpl.drainDeferrals() }

    /** Performs a transactional update of the Kairos network. */
    private fun LogIndent.doTransaction(evalScope: EvalScope) {
    private fun LogIndent.doTransaction(evalScope: EvalScope, coroutineScope: CoroutineScope) {
        // Traverse network, then run outputs
        logDuration({ "traverse network" }, trace = true) {
            do {
@@ -204,7 +199,7 @@ internal class Network(
                }
            )
        }
        coroutineScope.launch { evalLaunchedOutputs() }
        evalLaunchedOutputs(coroutineScope)
        // Update states
        logDuration({ "write states" }, trace = true) {
            runThenDrainDeferrals { evalStateWriters(currentLogIndent, evalScope) }
@@ -237,15 +232,11 @@ internal class Network(
        return true
    }

    private suspend fun evalLaunchedOutputs() {
        // Outputs might enqueue other outputs, so we need two loops
        while (outputsByDispatcher.isNotEmpty()) {
            var launchedAny = false
            coroutineScope {
    private fun evalLaunchedOutputs(coroutineScope: CoroutineScope) {
        if (outputsByDispatcher.isEmpty()) return
        for ((key, outputs) in outputsByDispatcher) {
            if (outputs.isNotEmpty()) {
                        launchedAny = true
                        launch(key) {
                coroutineScope.launch(key) {
                    while (outputs.isNotEmpty()) {
                        val output = outputs.removeFirst()
                        launch { output() }
@@ -253,12 +244,8 @@ internal class Network(
                }
            }
        }
            }
            if (!launchedAny) {
        outputsByDispatcher.clear()
    }
        }
    }

    private fun evalMuxMovers(logIndent: Int, evalScope: EvalScope) {
        while (muxMovers.isNotEmpty()) {