blob: c92634f844abdf3c2f8e145688c2c449dd454acf [file] [log] [blame]
Roman Elizarova7db8ec2017-12-21 22:45:12 +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 Elizarova7db8ec2017-12-21 22:45:12 +03003 */
4
Roman Elizarove1c0b652017-12-01 14:02:57 +03005package kotlinx.coroutines.experimental
6
Roman Elizarovaa461cf2018-04-11 13:20:29 +03007import kotlinx.coroutines.experimental.internal.*
8
Roman Elizarove1c0b652017-12-01 14:02:57 +03009/**
Vsevolod Tolstopyatovf3a50132018-04-16 19:41:20 +030010 * Handler for [Job.invokeOnCompletion] and [CancellableContinuation.invokeOnCancellation].
Roman Elizarove1c0b652017-12-01 14:02:57 +030011 *
12 * Installed handler should not throw any exceptions. If it does, they will get caught,
13 * wrapped into [CompletionHandlerException], and rethrown, potentially causing crash of unrelated code.
14 *
Roman Elizarove89cd682018-04-25 13:03:40 +030015 * The meaning of `cause` that is passed to the handler:
16 * * Cause is `null` when job has completed normally.
17 * * Cause is an instance of [CancellationException] when job was cancelled _normally_.
18 * **It should not be treated as an error**. In particular, it should not be reported to error logs.
19 * * Otherwise, the job had _failed_.
20 *
Roman Elizarove1c0b652017-12-01 14:02:57 +030021 * **Note**: This type is a part of internal machinery that supports parent-child hierarchies
22 * and allows for implementation of suspending functions that wait on the Job's state.
23 * This type should not be used in general application code.
24 * Implementations of `CompletionHandler` must be fast and _lock-free_.
25 */
26public typealias CompletionHandler = (cause: Throwable?) -> Unit
Roman Elizarovaa461cf2018-04-11 13:20:29 +030027
28// We want class that extends LockFreeLinkedListNode & CompletionHandler but we cannot do it on Kotlin/JS,
29// so this expect class provides us with the corresponding abstraction in a platform-agnostic way.
Roman Elizarovdbd9e1c2018-04-28 15:14:18 +030030internal expect abstract class CompletionHandlerBase() : LockFreeLinkedListNode {
Roman Elizarovaa461cf2018-04-11 13:20:29 +030031 abstract fun invoke(cause: Throwable?)
32}
33
Roman Elizarovdbd9e1c2018-04-28 15:14:18 +030034internal expect val CompletionHandlerBase.asHandler: CompletionHandler
35
36// More compact version of CompletionHandlerBase for CancellableContinuation with same workaround for JS
37internal expect abstract class CancelHandlerBase() {
Vsevolod Tolstopyatovf3a50132018-04-16 19:41:20 +030038 abstract fun invoke(cause: Throwable?)
39}
40
Roman Elizarovdbd9e1c2018-04-28 15:14:18 +030041internal expect val CancelHandlerBase.asHandler: CompletionHandler
42
Roman Elizarovaa461cf2018-04-11 13:20:29 +030043// :KLUDGE: We have to invoke a handler in platform-specific way via `invokeIt` extension,
44// because we play type tricks on Kotlin/JS and handler is not necessarily a function there
45internal expect fun CompletionHandler.invokeIt(cause: Throwable?)