@@ -6,28 +6,42 @@ package kotlinx.coroutines.time
6
6
import kotlinx.coroutines.CoroutineScope
7
7
import kotlinx.coroutines.selects.SelectBuilder
8
8
import java.time.Duration
9
- import java.util.concurrent.TimeUnit
10
9
11
10
/* *
12
11
* "java.time" adapter method for [kotlinx.coroutines.delay]
13
12
*/
14
13
public suspend fun delay (duration : Duration ) =
15
- kotlinx.coroutines.delay(duration.toMillis ())
14
+ kotlinx.coroutines.delay(duration.toMillisOrMax ())
16
15
17
16
/* *
18
17
* "java.time" adapter method for [SelectBuilder.onTimeout]
19
18
*/
20
19
public fun <R > SelectBuilder<R>.onTimeout (duration : Duration , block : suspend () -> R ) =
21
- onTimeout(duration.toMillis (), block)
20
+ onTimeout(duration.toMillisOrMax (), block)
22
21
23
22
/* *
24
23
* "java.time" adapter method for [kotlinx.coroutines.withTimeout]
25
24
*/
26
25
public suspend fun <T > withTimeout (duration : Duration , block : suspend CoroutineScope .() -> T ): T =
27
- kotlinx.coroutines.withTimeout(duration.toMillis (), block)
26
+ kotlinx.coroutines.withTimeout(duration.toMillisOrMax (), block)
28
27
29
28
/* *
30
29
* "java.time" adapter method for [kotlinx.coroutines.withTimeoutOrNull]
31
30
*/
32
31
public suspend fun <T > withTimeoutOrNull (duration : Duration , block : suspend CoroutineScope .() -> T ): T ? =
33
- kotlinx.coroutines.withTimeoutOrNull(duration.toMillis(), block)
32
+ kotlinx.coroutines.withTimeoutOrNull(duration.toMillisOrMax(), block)
33
+
34
+ /* *
35
+ * Try to convert a [Duration] to milliseconds, negative durations are translated to `0`,
36
+ * too large durations are capped to `Duration.ofMillis(Long.MAX_VALUE)`.
37
+ */
38
+ private fun Duration.toMillisOrMax (): Long {
39
+ // values of Duration.ofMillis(Long.MAX_VALUE)
40
+ val maxSeconds = 9223372036854775
41
+ val maxNanos = 807000000
42
+ return when {
43
+ isNegative -> 0
44
+ seconds < maxSeconds || seconds == maxSeconds && nano < maxNanos -> toMillis()
45
+ else -> Long .MAX_VALUE
46
+ }
47
+ }
0 commit comments