Мьютекс не содержится в этом асинхронном блоке

#mutex #android-livedata #flow #kotlin-coroutines

Вопрос:

Я выполняю расширенные сопрограммы с помощью Kotlin flow и лаборатории кода LiveData и столкнулся с этой функцией CacheOnSuccess.kt .

Есть комментарий, в котором говорится: «/ / Примечание: мьютекс не содержится в этом асинхронном блоке». Что именно это означает? Почему бы мьютексу не храниться в асинхронном блоке? И в чем же заключается значение этого?

     suspend fun getOrAwait(): T {
        return supervisorScope {
            // This function is thread-safe _iff_ deferred is @Volatile and all reads and writes
            // hold the mutex.

            // only allow one coroutine to try running block at a time by using a coroutine-base
            // Mutex
            val currentDeferred = mutex.withLock {
                deferred?.let { return@withLock it }

                async {
                    // Note: mutex is not held in this async block
                    block()
                }.also {
                    // Note: mutex is held here
                    deferred = it
                }
            }

            // await the result, with our custom error handling
            currentDeferred.safeAwait()
        }
    }
 

Ответ №1:

по данным withLock осуществления, мьютекс удерживается на просто стек-кадр, а значит, после withLock выполнения мьютекс освобождается, но код внутри асинхронного может не выполнить правы в том, что рама (возможно, в другом потоке по текущим диспетчеров), так что, вероятно, когда блок асинхронного казнят, withLock вызов может уже вернулись, как для also вызова, он помечается как inline , таким образом, он выполняется в текущем кадре, прямо перед withLock возвращается

Ответ №2:

Мьютекс удерживается не более чем одной сопрограммой в любое время. async запускает сопрограмму, которая не пытается получить мьютекс. Значение этого такое же, как и для любого другого мьютекса-код внутри async блока не защищен мьютексом, поэтому он не должен касаться состояния, которое требуется для его защиты.