Today I needed this: ```class SuspendAtomicRef<...
# coroutines
s
Today I needed this:
Copy code
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
Odd, why not just use an atomic ref? Would be faster.
s
It for an optimization so reducing multiple
init
invocations the entire point of it
d
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
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.