/**
* Persistent context for the coroutine. It is an indexed set of [Element] instances.
* An indexed set is a mix between a set and a map.
* Every element in this set has a unique [Key].
*/
publicinterfaceElement:CoroutineContext{/**
* A key of this coroutine context element.
*/publicvalkey:Key<*>publicoverrideoperatorfun<E:Element>get(key:Key<E>):E?=@Suppress("UNCHECKED_CAST")if(this.key==key)thisasEelsenullpublicoverridefun<R>fold(initial:R,operation:(R,Element)->R):R=operation(initial,this)publicoverridefunminusKey(key:Key<*>):CoroutineContext=if(this.key==key)EmptyCoroutineContextelsethis}
一个CoroutineContext+另一个CoroutineContext的写法很常见,实际上是CoroutineContext中定义了operator fun plus方法,可以用+调用。翻开源码可以注意到组合时总是要先把ContinuationInterceptor放到链表(CombinedContext)最前面的位置以保证最先执行。
/**
* Defines start options for coroutines builders.
*
* It is used in the `start` parameter of coroutine builder functions like
* [launch][CoroutineScope.launch] and [async][CoroutineScope.async]
* to describe when and how the coroutine should be dispatched initially.
*
* This parameter only affects how the coroutine behaves until the code of its body starts executing.
* After that, cancellability and dispatching are defined by the behavior of the invoked suspending functions.
*
* The summary of coroutine start options is:
* - [DEFAULT] immediately schedules the coroutine for execution according to its context.
* - [LAZY] delays the moment of the initial dispatch until the result of the coroutine is needed.
* - [ATOMIC] prevents the coroutine from being cancelled before it starts, ensuring that its code will start
* executing in any case.
* - [UNDISPATCHED] immediately executes the coroutine until its first suspension point _in the current thread_.
*/
// kotlinx.coroutines.intrinsics.Cancelable.kt
/**
* Use this function to start coroutine in a cancellable way, so that it can be cancelled
* while waiting to be dispatched.
*/@InternalCoroutinesApipublicfun<T>(suspend()->T).startCoroutineCancellable(completion:Continuation<T>):Unit=runSafely(completion){createCoroutineUnintercepted(completion).intercepted().resumeCancellableWith(Result.success(Unit))}// kotlin.coroutines.jvm.internal.ContinuationImpl.kt
publicfunintercepted():Continuation<Any?>=intercepted?:(context[ContinuationInterceptor]?.interceptContinuation(this)?:this).also{intercepted=it}
/**
* Creates unintercepted coroutine without receiver and with result type [T].
* This function creates a new, fresh instance of suspendable computation every time it is invoked.
*
* To start executing the created coroutine, invoke `resume(Unit)` on the returned [Continuation] instance.
* The [completion] continuation is invoked when coroutine completes with result or exception.
*
* This function returns unintercepted continuation.
* Invocation of `resume(Unit)` starts coroutine immediately in the invoker's call stack without going through the
* [ContinuationInterceptor] that might be present in the completion's [CoroutineContext].
* It is the invoker's responsibility to ensure that a proper invocation context is established.
* Note that [completion] of this function may get invoked in an arbitrary context.
*
* [Continuation.intercepted] can be used to acquire the intercepted continuation.
* Invocation of `resume(Unit)` on intercepted continuation guarantees that execution of
* both the coroutine and [completion] happens in the invocation context established by
* [ContinuationInterceptor].
*
* Repeated invocation of any resume function on the resulting continuation corrupts the
* state machine of the coroutine and may result in arbitrary behaviour or exception.
*/@SinceKotlin("1.3")publicactualfun<T>(suspend()->T).createCoroutineUnintercepted(completion:Continuation<T>):Continuation<Unit>{valprobeCompletion=probeCoroutineCreated(completion)returnif(thisisBaseContinuationImpl)create(probeCompletion)elsecreateCoroutineFromSuspendFunction(probeCompletion){(thisasFunction1<Continuation<T>,Any?>).invoke(it)}}