@@ -11,12 +11,6 @@ import kotlin.jvm.*
11
11
12
12
@SharedImmutable
13
13
private val UNDEFINED = Symbol (" UNDEFINED" )
14
-
15
- // Internal to avoid synthetic accessors
16
- @SharedImmutable
17
- @JvmField
18
- internal val NON_REUSABLE = Symbol (" NON_REUSABLE" )
19
-
20
14
@SharedImmutable
21
15
@JvmField
22
16
internal val REUSABLE_CLAIMED = Symbol (" REUSABLE_CLAIMED" )
@@ -36,7 +30,8 @@ internal class DispatchedContinuation<in T>(
36
30
/* *
37
31
* Possible states of reusability:
38
32
*
39
- * 1) `null`. Cancellable continuation wasn't yet attempted to be reused.
33
+ * 1) `null`. Cancellable continuation wasn't yet attempted to be reused or
34
+ * way used and then invalidated (e.g. because of the cancellation).
40
35
* 2) [CancellableContinuation]. Continuation to be/that is being reused.
41
36
* 3) [REUSABLE_CLAIMED]. CC is currently being reused and its owner executes `suspend` block:
42
37
* ```
@@ -49,7 +44,6 @@ internal class DispatchedContinuation<in T>(
49
44
* ```
50
45
* 4) [Throwable] continuation was cancelled with this cause while being in [suspendAtomicCancellableCoroutineReusable],
51
46
* [CancellableContinuationImpl.getResult] will check for cancellation later.
52
- * 5) [NON_REUSABLE]. CC was cancelled at least once, thus cannot be longer reused.
53
47
*
54
48
* [REUSABLE_CLAIMED] state is required to prevent the lost resume in the channel.
55
49
* AbstractChannel.receive method relies on the fact that the following pattern
@@ -69,7 +63,7 @@ internal class DispatchedContinuation<in T>(
69
63
get() = _reusableCancellableContinuation .value as ? CancellableContinuationImpl <* >
70
64
71
65
public val isReusable: Boolean
72
- get() = _reusableCancellableContinuation .value. let { it != null && it != NON_REUSABLE }
66
+ get() = _reusableCancellableContinuation .value != null
73
67
74
68
/* *
75
69
* Claims the continuation for [suspendAtomicCancellableCoroutineReusable] block,
@@ -81,7 +75,6 @@ internal class DispatchedContinuation<in T>(
81
75
* Transitions:
82
76
* 1) `null` -> claimed, caller will instantiate CC instance
83
77
* 2) `CC` -> claimed, caller will reuse CC instance
84
- * 3) `NON_REUSABLE` -> nothing, proceed, caller will instantiate CC instance
85
78
*/
86
79
_reusableCancellableContinuation .loop { state ->
87
80
when {
@@ -98,7 +91,6 @@ internal class DispatchedContinuation<in T>(
98
91
return state as CancellableContinuationImpl <T >
99
92
}
100
93
}
101
- state == = NON_REUSABLE -> return null
102
94
else -> error(" Inconsistent state $state " )
103
95
}
104
96
}
@@ -125,24 +117,14 @@ internal class DispatchedContinuation<in T>(
125
117
state == = REUSABLE_CLAIMED -> if (_reusableCancellableContinuation .compareAndSet(REUSABLE_CLAIMED , continuation)) return null
126
118
state == = null -> return null
127
119
state is Throwable -> {
128
- require(_reusableCancellableContinuation .compareAndSet(state, NON_REUSABLE ))
120
+ require(_reusableCancellableContinuation .compareAndSet(state, null ))
129
121
return state
130
122
}
131
123
else -> return null // Is not reusable
132
124
}
133
125
}
134
126
}
135
127
136
- fun makeCancellationNonReusable () {
137
- _reusableCancellableContinuation .loop { state ->
138
- when (state) {
139
- // Do not overwrite cancellation (cancelled CC can't be reused anyway)
140
- is Throwable -> return
141
- else -> if (_reusableCancellableContinuation .compareAndSet(state, NON_REUSABLE )) return
142
- }
143
- }
144
- }
145
-
146
128
/* *
147
129
* Tries to postpone cancellation if reusable CC is currently in [REUSABLE_CLAIMED] state.
148
130
* Returns `true` if cancellation is (or previously was) postponed, `false` otherwise.
@@ -156,7 +138,8 @@ internal class DispatchedContinuation<in T>(
156
138
}
157
139
is Throwable -> return true
158
140
else -> {
159
- if (_reusableCancellableContinuation .compareAndSet(state, NON_REUSABLE ))
141
+ // Invalidate
142
+ if (_reusableCancellableContinuation .compareAndSet(state, null ))
160
143
return false
161
144
}
162
145
}
0 commit comments