publicsuspendinlinefun<T>suspendCancellableCoroutine( crossinline block: (CancellableContinuation<T>) -> Unit ): T = suspendCoroutineUninterceptedOrReturn { uCont -> val cancellable = CancellableContinuationImpl(uCont.intercepted(), resumeMode = MODE_CANCELLABLE) /* * For non-atomic cancellation we setup parent-child relationship immediately * in case when`block`blocks the current thread (e.g. Rx2 with trampoline scheduler), but * properly supports cancellation. */ cancellable.initCancellability() block(cancellable) cancellable.getResult() }
privatefuninitializeDefaultDelay(): Delay { // Opt-out flag if (!defaultMainDelayOptIn) return DefaultExecutor val main = Dispatchers.Main /* * When we already are working with UI and Main threads, it makes * no sense to create a separate thread with timer that cannot be controller * by the UI runtime. */ returnif (main.isMissing() || main !is Delay) DefaultExecutor else main }
internalabstractclassEventLoopImplBase: EventLoopImplPlatform(), Delay { ... overridefunscheduleResumeAfterDelay(timeMillis: Long, continuation: CancellableContinuation<Unit>) { val timeNanos = delayToNanos(timeMillis) if (timeNanos < MAX_DELAY_NS) { val now = nanoTime() DelayedResumeTask(now + timeNanos, continuation).also { task -> /* * Order is important here: first we schedule the heap and only then * publish it to continuation. Otherwise,`DelayedResumeTask`would * have to know how to be disposed of even when it wasn't scheduled yet. */ schedule(now, task) continuation.disposeOnCancellation(task) } } } ... }