https://kotlinlang.org logo
Title
s

spand

04/15/2021, 6:19 AM
Today I needed this:
class SuspendAtomicRef<T : Any> {
    private var data: T? = null
    private val mutex = Mutex()

    suspend fun getOrSet(init: suspend () -> T): T {
        return mutex.withLock {
            data ?: init().also { data = it }
        }
    }
}
Seems pretty basic so I wonder if I am missing it in the coroutines library?
d

Dominaezzz

04/15/2021, 7:44 AM
Odd, why not just use an atomic ref? Would be faster.
s

spand

04/15/2021, 7:51 AM
It for an optimization so reducing multiple
init
invocations the entire point of it
d

Dominaezzz

04/15/2021, 7:53 AM
Ah, I missed the init part.
Given you still hit the mutex even after initialisation, there's still much room for improvement.
I also feel like I would refactor my code to not need this but that's probably just ignorance due to lack of use case.
s

spand

04/16/2021, 5:01 AM
Thanks for the hint @ephemient. I was actually using Louis suspendLazy previously but it sucks for properties. I think my
SuspendAtomicRef
work better in that: 1. Needs no coroutine on allocation (great for properties) 2. Supports cancellation much better in that a cancelled
init
will not break or block the others waiting.