@@ -72,7 +72,7 @@ internal fun scheduledExecutorShutdownNowAndRelease() {
72
72
* The code that is executing inside the [block] is cancelled on timeout and the active or next invocation of
73
73
* cancellable suspending function inside the block throws [CancellationException], so normally that exception,
74
74
* if uncaught, also gets thrown by `withTimeout` as a result.
75
- * However, the code in the block can suppresses [CancellationException].
75
+ * However, the code in the block can suppress [CancellationException].
76
76
*
77
77
* The sibling function that does not throw exception on timeout is [withTimeoutOrNull].
78
78
* Note, that timeout action can be specified for [select] invocation with [onTimeout][SelectBuilder.onTimeout] clause.
@@ -107,19 +107,19 @@ private class TimeoutExceptionCoroutine<in T>(
107
107
private val cont : Continuation <T >
108
108
) : JobSupport(active = true ), Runnable, Continuation<T> {
109
109
override val context: CoroutineContext = cont.context + this // mix in this Job into the context
110
- override fun run () { cancel(TimeoutException (time, unit)) }
110
+ override fun run () { cancel(TimeoutException (time, unit, this )) }
111
111
override fun resume (value : T ) { cont.resumeDirect(value) }
112
112
override fun resumeWithException (exception : Throwable ) { cont.resumeDirectWithException(exception) }
113
113
}
114
114
115
115
/* *
116
116
* Runs a given suspending block of code inside a coroutine with a specified timeout and returns
117
- * `null` if timeout was exceeded.
117
+ * `null` if this timeout was exceeded.
118
118
*
119
119
* The code that is executing inside the [block] is cancelled on timeout and the active or next invocation of
120
120
* cancellable suspending function inside the block throws [CancellationException]. Normally that exception,
121
121
* if uncaught by the block, gets converted into the `null` result of `withTimeoutOrNull`.
122
- * However, the code in the block can suppresses [CancellationException].
122
+ * However, the code in the block can suppress [CancellationException].
123
123
*
124
124
* The sibling function that throws exception on timeout is [withTimeout].
125
125
* Note, that timeout action can be specified for [select] invocation with [onTimeout][SelectBuilder.onTimeout] clause.
@@ -158,14 +158,18 @@ private class TimeoutNullCoroutine<in T>(
158
158
private val cont : Continuation <T ?>
159
159
) : JobSupport(active = true ), Runnable, Continuation<T> {
160
160
override val context: CoroutineContext = cont.context + this // mix in this Job into the context
161
- override fun run () { cancel(TimeoutException (time, unit)) }
161
+ override fun run () { cancel(TimeoutException (time, unit, this )) }
162
162
override fun resume (value : T ) { cont.resumeDirect(value) }
163
163
override fun resumeWithException (exception : Throwable ) {
164
164
// suppress inner timeout exception and replace it with null
165
- if (exception is TimeoutException )
165
+ if (exception is TimeoutException && exception.coroutine == = this )
166
166
cont.resumeDirect(null ) else
167
167
cont.resumeDirectWithException(exception)
168
168
}
169
169
}
170
170
171
- private class TimeoutException (time : Long , unit : TimeUnit ) : CancellationException(" Timed out waiting for $time $unit " )
171
+ private class TimeoutException (
172
+ time : Long ,
173
+ unit : TimeUnit ,
174
+ @JvmField val coroutine : Job
175
+ ) : CancellationException(" Timed out waiting for $time $unit " )
0 commit comments