Open
Description
Version: 1.6
I was surprised to see that while a job is completing (i.e., waiting for all of its children to complete) new children can still be launched. In contrast, when a job is complete, new children get canceled automatically.
This forces me to keep track myself whether I'm draining a job and avoid calling launch if so.
Here is the repro:
fun main() = runBlocking {
val job = Job()
val scope = CoroutineScope(job)
val sema = Semaphore(1, 1)
scope.launch {
sema.acquire()
}
job.complete() // transitions to completing until the above coroutine completes
val c1 = scope.launch {
println("don't think this should run") // this runs
}
c1.join()
// cleanup
sema.release()
job.join()
}