blob: 398885f64c402f3479166b843361360efad7f144 [file] [log] [blame]
Roman Elizarovaa461cf2018-04-11 13:20:29 +03001/*
Roman Elizarov1f74a2d2018-06-29 19:19:45 +03002 * Copyright 2016-2018 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
8package kotlinx.coroutines.experimental
9
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 * ```
Roman Elizarov27b8f452018-09-20 21:23:41 +030018 *
19 * @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 =
Vsevolod Tolstopyatovf3a50132018-04-16 19:41:20 +030023 invokeOnCompletion(handler = CancelFutureOnCompletion(this, future)) // TODO make it work only on cancellation as well?
24
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 * ```
29 * invokeOnCompletion { future.cancel(false) }
30 * ```
31 */
32@Deprecated(
33 message = "Disposable handlers on regular completion are no longer supported",
34 replaceWith = ReplaceWith("cancelFutureOnCancellation(future)"),
Vsevolod Tolstopyatov2cd27fb2018-06-07 13:22:17 +030035 level = DeprecationLevel.WARNING)
Vsevolod Tolstopyatovf3a50132018-04-16 19:41:20 +030036public fun CancellableContinuation<*>.cancelFutureOnCompletion(future: Future<*>): DisposableHandle {
37 cancelFutureOnCancellation(future)
38 return NonDisposableHandle
39}
40
41/**
42 * Cancels a specified [future] when this job is cancelled.
43 * This is a shortcut for the following code with slightly more efficient implementation (one fewer object created).
44 * ```
45 * invokeOnCancellation { future.cancel(false) }
46 * ```
47 */
Roman Elizarovdbd9e1c2018-04-28 15:14:18 +030048public fun CancellableContinuation<*>.cancelFutureOnCancellation(future: Future<*>) =
49 invokeOnCancellation(handler = CancelFutureOnCancel(future))
Roman Elizarovaa461cf2018-04-11 13:20:29 +030050
51private class CancelFutureOnCompletion(
52 job: Job,
53 private val future: Future<*>
54) : JobNode<Job>(job) {
Roman Elizarovdbd9e1c2018-04-28 15:14:18 +030055 override fun invoke(cause: Throwable?) {
Roman Elizarovaa461cf2018-04-11 13:20:29 +030056 // Don't interrupt when cancelling future on completion, because no one is going to reset this
57 // interruption flag and it will cause spurious failures elsewhere
58 future.cancel(false)
59 }
60 override fun toString() = "CancelFutureOnCompletion[$future]"
61}
62
Roman Elizarovdbd9e1c2018-04-28 15:14:18 +030063private class CancelFutureOnCancel(private val future: Future<*>) : CancelHandler() {
64 override fun invoke(cause: Throwable?) {
Vsevolod Tolstopyatovf3a50132018-04-16 19:41:20 +030065 // Don't interrupt when cancelling future on completion, because no one is going to reset this
66 // interruption flag and it will cause spurious failures elsewhere
67 future.cancel(false)
68 }
Roman Elizarovdbd9e1c2018-04-28 15:14:18 +030069 override fun toString() = "CancelFutureOnCancel[$future]"
Vsevolod Tolstopyatovf3a50132018-04-16 19:41:20 +030070}