File tree 4 files changed +104
-2
lines changed
common/kotlinx-coroutines-core-common
4 files changed +104
-2
lines changed Original file line number Diff line number Diff line change @@ -214,7 +214,7 @@ public suspend fun <T> withContext(
214
214
}
215
215
}
216
216
// SLOW PATH -- use new dispatcher
217
- val coroutine = DispatchedCoroutine (newContext, uCont) // MODE_DISPATCHED
217
+ val coroutine = DispatchedCoroutine (newContext, uCont) // MODE_ATOMIC_DEFAULT
218
218
coroutine.initParentJob()
219
219
block.startCoroutineCancellable(coroutine, coroutine)
220
220
coroutine.getResult()
@@ -292,7 +292,7 @@ private class DispatchedCoroutine<in T>(
292
292
context : CoroutineContext ,
293
293
uCont : Continuation <T >
294
294
) : ScopeCoroutine<T>(context, uCont) {
295
- override val defaultResumeMode: Int get() = MODE_CANCELLABLE
295
+ override val defaultResumeMode: Int get() = MODE_ATOMIC_DEFAULT
296
296
297
297
// this is copy-and-paste of a decision state machine inside AbstractionContinuation
298
298
// todo: we may some-how abstract it via inline class
Original file line number Diff line number Diff line change @@ -219,6 +219,30 @@ class CoroutineScopeTest : TestBase() {
219
219
}
220
220
}
221
221
222
+ @Test
223
+ fun testCoroutineScopeCancellationVsException () = runTest {
224
+ expect(1 )
225
+ var job: Job ? = null
226
+ job = launch(start = CoroutineStart .UNDISPATCHED ) {
227
+ expect(2 )
228
+ try {
229
+ coroutineScope {
230
+ expect(3 )
231
+ yield () // must suspend
232
+ expect(5 )
233
+ job!! .cancel() // cancel this job _before_ it throws
234
+ throw TestException1 ()
235
+ }
236
+ } catch (e: TestException1 ) {
237
+ // must have caught TextException
238
+ expect(6 )
239
+ }
240
+ }
241
+ expect(4 )
242
+ yield () // to coroutineScope
243
+ finish(7 )
244
+ }
245
+
222
246
@Test
223
247
fun testScopePlusContext () {
224
248
assertSame(EmptyCoroutineContext , scopePlusContext(EmptyCoroutineContext , EmptyCoroutineContext ))
Original file line number Diff line number Diff line change @@ -195,6 +195,30 @@ class SupervisorTest : TestBase() {
195
195
assertTrue(parent.isCancelled)
196
196
}
197
197
198
+ @Test
199
+ fun testSupervisorScopeCancellationVsException () = runTest {
200
+ expect(1 )
201
+ var job: Job ? = null
202
+ job = launch(start = CoroutineStart .UNDISPATCHED ) {
203
+ expect(2 )
204
+ try {
205
+ supervisorScope {
206
+ expect(3 )
207
+ yield () // must suspend
208
+ expect(5 )
209
+ job!! .cancel() // cancel this job _before_ it throws
210
+ throw TestException1 ()
211
+ }
212
+ } catch (e: TestException1 ) {
213
+ // must have caught TextException
214
+ expect(6 )
215
+ }
216
+ }
217
+ expect(4 )
218
+ yield () // to coroutineScope
219
+ finish(7 )
220
+ }
221
+
198
222
private class TestException1 : Exception ()
199
223
private class TestException2 : Exception ()
200
224
}
Original file line number Diff line number Diff line change @@ -139,6 +139,60 @@ class WithContextTest : TestBase() {
139
139
}
140
140
}
141
141
142
+ @Test
143
+ fun testRunCancellationUndispatchedVsException () = runTest {
144
+ expect(1 )
145
+ var job: Job ? = null
146
+ job = launch(start = CoroutineStart .UNDISPATCHED ) {
147
+ expect(2 )
148
+ try {
149
+ // Same dispatcher, different context
150
+ withContext(CoroutineName (" testRunCancellationUndispatchedVsException" )) {
151
+ expect(3 )
152
+ yield () // must suspend
153
+ expect(5 )
154
+ job!! .cancel() // cancel this job _before_ it throws
155
+ throw TestException ()
156
+ }
157
+ } catch (e: TestException ) {
158
+ // must have caught TextException
159
+ expect(6 )
160
+ }
161
+ }
162
+ expect(4 )
163
+ yield () // to coroutineScope
164
+ finish(7 )
165
+ }
166
+
167
+ @Test
168
+ fun testRunCancellationDispatchedVsException () = runTest {
169
+ expect(1 )
170
+ var job: Job ? = null
171
+ job = launch(start = CoroutineStart .UNDISPATCHED ) {
172
+ expect(2 )
173
+ try {
174
+ // "Different" dispatcher (schedules execution back and forth)
175
+ withContext(wrapperDispatcher(coroutineContext)) {
176
+ expect(4 )
177
+ yield () // must suspend
178
+ expect(6 )
179
+ job!! .cancel() // cancel this job _before_ it throws
180
+ throw TestException ()
181
+ }
182
+ } catch (e: TestException ) {
183
+ // must have caught TextException
184
+ expect(8 )
185
+ }
186
+ }
187
+ expect(3 )
188
+ yield () // withContext is next
189
+ expect(5 )
190
+ yield () // withContext again
191
+ expect(7 )
192
+ yield () // to catch block
193
+ finish(9 )
194
+ }
195
+
142
196
@Test
143
197
fun testRunSelfCancellationWithException () = runTest(unhandled = listOf ({e -> e is AssertionError })) {
144
198
expect(1 )
You can’t perform that action at this time.
0 commit comments