Can anyone explain what `CoroutineStart.ATOMIC` do...
# coroutines
s
Can anyone explain what
CoroutineStart.ATOMIC
does? The documentation isn't very clear to me.
a
I believe guarantees that the coroutine will start before being cancelled. For example this:
Copy code
val job = launch { /* Will never run */ }
job.cancel()
vs
Copy code
val job = launch(start = ATOMIC) { 
  /* Will run but isCancelled will be true */ 
}
job.cancel()
s
so it will run to completion every time?
u
it can be canceled at the first suspension point
a
Well it will always start it but it will be in a cancelled state so any attempt to suspend it will fail
u
Here is an example from the android world:
Copy code
fun ring(context: Context) {
    val pm = context.powerManager
    val wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "AlarmHandover")
    wakeLock.acquire()

    // Launch coroutine ATOMIC to make sure at least the finally block is executed and can release the wake lock
    GlobalScope.launch(Dispatchers.Main, CoroutineStart.ATOMIC) {
        try {
            /// Start ringing an alarm.
        } finally {
            wakeLock.release()
        }
    }
}
In this case, I need to acquire a wake lock before launching a coroutine, because otherwise the device will go right back to sleep, after I return from ring(). If then the launched coroutine get's canceled, before it enters the try clause, the wake lock would never be released.
s
more than just the finally block is guaranteed to run if it's cancelled right? The entire try block should still complete even if it's cancelled?
u
not if you have a suspension point in it. if it is immediately canceled, it is guaranteed to still start the coroutine but as any other coroutine will terminate the next time it suspends
a
The finally block is always called but it doesn’t work if the things you call suspend and if that throws