Hello, I'm working on converting a callback from a...
# coroutines
a
Hello, I'm working on converting a callback from a C library into a suspend function. I'm considering using :
Copy code
suspend fun myFun() {
    val atomicLong = AtomicReference<Long?>(null)

    externalFunctionWithCallback { value ->
        atomicLong.set(value)
    }

    while (atomicLong.get() == null) {
        yield()
    }

    return atomicLong.get()
}
Or may be this one
Copy code
suspend fun myFun() {
    val atomicLong = AtomicReference<Long?>(null)

    externalFunctionWithCallback { value ->
        atomicLong.set(value)
    }

    while (atomicLong.get() == null) {
        delay(1000)
    }

    return atomicLong.get()
}
What do you think? The goal would be to let other coroutine run while I'm waiting something
s
Did you consider using
suspendCoroutine
(or
suspendCancellableCoroutine
)?
j
Ah, you beat me to it 😅
🫰 1
s
Copy code
suspend fun myFun() = suspendCoroutine<Long> { cont ->
  externalFunctionWithCallback { value ->
    cont.resume(value)
  }
}
☝️ 1
1
a
Thanks I will check that !
j
And if the external function somehow allows cancellation, you could use the
suspendCancellableCoroutine
variant to make it cooperate with coroutines cancellation:
Copy code
suspend fun myFun() = suspendCancellableCoroutine<Long> { cont ->

  // you could also put this after the external call depending on the API to cancel
  cont.invokeOnCancellation { ...cancel/stop/cleanup code here... }

  externalFunctionWithCallback { value ->
    cont.resume(value)
  }
}
Note that you could also use this variant if the external function does NOT support cancellation (thus without the
invokeOnCancellation
call), but if you do this, you will technically leak the non-cancelled external function call, which is probably a bad idea
👍 1