Another possibility might be ``` val coroJob = ...
# coroutines
n
Another possibility might be
Copy code
val coroJob = AtomicReference<Job> ()
    /// Start my coroutine, may be called from any thread
    fun startCoro () {

        val coro = coroutineScope.launch(<http://Dispatchers.IO|Dispatchers.IO>, start = LAZY) {
            // Do the actual work here ...
            coroJob.set(null)
        }

        // If coroJob isn't null, do nothing.
        if (coroJob.compareAndSet(null, coro))
            coro.start()
    }
which avoids the explicit context switches and should still be thread-safe. Is there a more idiomatic and safe way to do that?
u
What happens if you make coro a property and just start it multiple times?
n
Dunno, probably an exception 😉
u
Dunno? But are you interested in finding out? You could check the kdoc. It might solve your problem?
n
Ah, it will simply return false and not do anything if that coro was already started or completed. So not very useful here.
u
Isn't that what you want? Star a coro the first time startCoro is called and do nothing if it is already started?
n
but i want to re-start it if it was completed
u
I see. Then I guess it does not get much simpler then what you have.
Just watch out for a coroutine leak. In the code above, you are always launching a new coroutine, leaving it dangling in the
NEW
state.
n
It's not launched, just created (lazy)... Doesn't it get GC'd?
u
No. It is launched lazy
n
But there isn't any reference to the Job, so it can't ever be launched, so the GC should collect it?
u
I would expect it to stay around
if you start it, there still is no ref and it would live until completed
n
maybe an
else coro.cancel()
would help
u
How about this one?
Copy code
val coroRunning = AtomicBoolean(false)

/// Start my coroutine, may be called from any thread
fun startCoro () {
    // If coro is running, do nothing.
    if (coroRunning.compareAndExchange(false, true)) {
        coroutineScope.launch(<http://Dispatchers.IO|Dispatchers.IO>) {
            // Do the actual work here ...
            coroRunning.set(false)
        }
    }
}
n
looks nice... Hmm, I think some requirements changed and I have to do the whole thing differently 🤦‍♂️ thanks anyways 😄
u
🙂 - Good luck