blob: bd16f49af021eb8ff8b14f361a7b066399c7502e [file] [log] [blame]
Roman Elizarovaa461cf2018-04-11 13:20:29 +03001/*
Aurimas Liutikas7b140462021-05-12 21:56:16 +00002 * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
Roman Elizarovaa461cf2018-04-11 13:20:29 +03003 */
4
5@file:JvmMultifileClass
6@file:JvmName("JobKt")
7
Roman Elizarov0950dfa2018-07-13 10:33:25 +03008package kotlinx.coroutines
Roman Elizarovaa461cf2018-04-11 13:20:29 +03009
10import java.util.concurrent.*
11
12/**
Vsevolod Tolstopyatovf3a50132018-04-16 19:41:20 +030013 * Cancels a specified [future] when this job is cancelled.
Roman Elizarovaa461cf2018-04-11 13:20:29 +030014 * This is a shortcut for the following code with slightly more efficient implementation (one fewer object created).
15 * ```
16 * invokeOnCompletion { future.cancel(false) }
17 * ```
Vsevolod Tolstopyatov1f7b2d82018-10-09 15:57:51 +030018 *
Roman Elizarov27b8f452018-09-20 21:23:41 +030019 * @suppress **This an internal API and should not be used from general code.**
Roman Elizarovaa461cf2018-04-11 13:20:29 +030020 */
Roman Elizarov27b8f452018-09-20 21:23:41 +030021@InternalCoroutinesApi
Roman Elizarovaa461cf2018-04-11 13:20:29 +030022public fun Job.cancelFutureOnCompletion(future: Future<*>): DisposableHandle =
Aurimas Liutikas7b140462021-05-12 21:56:16 +000023 invokeOnCompletion(handler = CancelFutureOnCompletion(this, future)) // TODO make it work only on cancellation as well?
Vsevolod Tolstopyatovf3a50132018-04-16 19:41:20 +030024
25/**
26 * Cancels a specified [future] when this job is cancelled.
27 * This is a shortcut for the following code with slightly more efficient implementation (one fewer object created).
28 * ```
Vsevolod Tolstopyatovf3a50132018-04-16 19:41:20 +030029 * invokeOnCancellation { future.cancel(false) }
30 * ```
31 */
Vsevolod Tolstopyatov9cbad7d2020-03-27 17:43:45 +030032public fun CancellableContinuation<*>.cancelFutureOnCancellation(future: Future<*>): Unit =
Roman Elizarovdbd9e1c2018-04-28 15:14:18 +030033 invokeOnCancellation(handler = CancelFutureOnCancel(future))
Roman Elizarovaa461cf2018-04-11 13:20:29 +030034
35private class CancelFutureOnCompletion(
Aurimas Liutikas7b140462021-05-12 21:56:16 +000036 job: Job,
Roman Elizarovaa461cf2018-04-11 13:20:29 +030037 private val future: Future<*>
Aurimas Liutikas7b140462021-05-12 21:56:16 +000038) : JobNode<Job>(job) {
Roman Elizarovdbd9e1c2018-04-28 15:14:18 +030039 override fun invoke(cause: Throwable?) {
Roman Elizarovaa461cf2018-04-11 13:20:29 +030040 // Don't interrupt when cancelling future on completion, because no one is going to reset this
41 // interruption flag and it will cause spurious failures elsewhere
42 future.cancel(false)
43 }
Aurimas Liutikas7b140462021-05-12 21:56:16 +000044 override fun toString() = "CancelFutureOnCompletion[$future]"
Roman Elizarovaa461cf2018-04-11 13:20:29 +030045}
46
Roman Elizarovdbd9e1c2018-04-28 15:14:18 +030047private class CancelFutureOnCancel(private val future: Future<*>) : CancelHandler() {
48 override fun invoke(cause: Throwable?) {
Vsevolod Tolstopyatovf3a50132018-04-16 19:41:20 +030049 // Don't interrupt when cancelling future on completion, because no one is going to reset this
50 // interruption flag and it will cause spurious failures elsewhere
51 future.cancel(false)
52 }
Roman Elizarovdbd9e1c2018-04-28 15:14:18 +030053 override fun toString() = "CancelFutureOnCancel[$future]"
Vsevolod Tolstopyatovf3a50132018-04-16 19:41:20 +030054}