@@ -76,17 +76,36 @@ internal fun updateUndispatchedCompletion(context: CoroutineContext, oldValue: A
76
76
return undispatched
77
77
}
78
78
79
+ /* *
80
+ * Undispatched marker required to properly locate undispatched switch points and restore thread-local context to its initial value.
81
+ * Is not added as is as job to avoid being overridden.
82
+ *
83
+ * `var` is required to avoid cyclic initialization problem with `this`. It's late-binded once in the
84
+ * [UndispatchedCoroutine] ctor.
85
+ */
86
+ internal class UndispatchedMarker (
87
+ @JvmField var coroutine : UndispatchedCoroutine <* >?
88
+ ) : AbstractCoroutineContextElement(Key ) {
89
+ companion object Key : CoroutineContext.Key<UndispatchedMarker>
90
+ }
79
91
80
92
// Used by withContext when context changes, but dispatcher stays the same
81
- internal actual class UndispatchedCoroutine <in T > actual constructor (
93
+ internal actual class UndispatchedCoroutine <in T >(
82
94
context : CoroutineContext ,
95
+ marker : UndispatchedMarker ,
83
96
uCont : Continuation <T >
84
- ) : ScopeCoroutine<T>(context + UndispatchedMarker (null), uCont) {
97
+ ) : ScopeCoroutine<T>(context + marker, uCont) {
98
+
99
+ actual constructor (
100
+ context: CoroutineContext ,
101
+ uCont: Continuation <T >
102
+ ) : this (context, UndispatchedMarker (null ), uCont)
103
+
85
104
private var savedContext: CoroutineContext ? = null
86
105
private var savedOldValue: Any? = null
87
106
88
107
init {
89
- parentContext[ UndispatchedMarker ] !! .coroutine = this
108
+ marker .coroutine = this
90
109
}
91
110
92
111
fun saveThreadContext (context : CoroutineContext , oldValue : Any? ) {
0 commit comments