diff --git a/kotlinx-coroutines-core/README.md b/kotlinx-coroutines-core/README.md index f930794c87..2dc751ea2e 100644 --- a/kotlinx-coroutines-core/README.md +++ b/kotlinx-coroutines-core/README.md @@ -1,6 +1,6 @@ # Module kotlinx-coroutines-core -Core primitives to work with coroutines, available on all platforms. +Core primitives to work with coroutines. Coroutine builder functions: @@ -84,13 +84,9 @@ Select expression to perform multiple suspending operations simultaneously until Low-level primitives for finer-grained control of coroutines. -# Package kotlinx.coroutines.timeunit - -Optional time unit support for multiplatform projects. - # Package kotlinx.coroutines.test -Components to ease writing unit-tests for code that contains coroutines with delays and timeouts. +Obsolete and deprecated module to test coroutines. Replaced with `kotlinx-coroutines-test` module. diff --git a/kotlinx-coroutines-core/common/README.md b/kotlinx-coroutines-core/common/README.md index ea4e53b5e2..b84cedf4d4 100644 --- a/kotlinx-coroutines-core/common/README.md +++ b/kotlinx-coroutines-core/common/README.md @@ -1,6 +1,6 @@ # Module kotlinx-coroutines-core -Core primitives to work with coroutines. +Core primitives to work with coroutines available on all platforms. Coroutine builder functions: @@ -10,7 +10,6 @@ Coroutine builder functions: | [async] | [Deferred] | [CoroutineScope] | Returns a single value with the future result | [produce][kotlinx.coroutines.channels.produce] | [ReceiveChannel][kotlinx.coroutines.channels.ReceiveChannel] | [ProducerScope][kotlinx.coroutines.channels.ProducerScope] | Produces a stream of elements | [actor][kotlinx.coroutines.channels.actor] | [SendChannel][kotlinx.coroutines.channels.SendChannel] | [ActorScope][kotlinx.coroutines.channels.ActorScope] | Processes a stream of messages -| [runBlocking] | `T` | [CoroutineScope] | Blocks the thread while the coroutine runs Coroutine dispatchers implementing [CoroutineDispatcher]: @@ -96,14 +95,6 @@ Select expression to perform multiple suspending operations simultaneously until Low-level primitives for finer-grained control of coroutines. -# Package kotlinx.coroutines.timeunit - -Optional time unit support for multiplatform projects. - -# Package kotlinx.coroutines.test - -Components to ease writing unit-tests for code that contains coroutines with delays and timeouts. - [launch]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/launch.html @@ -111,7 +102,6 @@ Components to ease writing unit-tests for code that contains coroutines with del [CoroutineScope]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-scope/index.html [async]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/async.html [Deferred]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/index.html -[runBlocking]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/run-blocking.html [CoroutineDispatcher]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-dispatcher/index.html [Dispatchers.Default]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-dispatchers/-default.html [Dispatchers.Unconfined]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-dispatchers/-unconfined.html diff --git a/kotlinx-coroutines-core/common/src/Builders.common.kt b/kotlinx-coroutines-core/common/src/Builders.common.kt index 26fd8e7050..4c42e5e183 100644 --- a/kotlinx-coroutines-core/common/src/Builders.common.kt +++ b/kotlinx-coroutines-core/common/src/Builders.common.kt @@ -60,6 +60,9 @@ public fun CoroutineScope.launch( /** * Creates a coroutine and returns its future result as an implementation of [Deferred]. * The running coroutine is cancelled when the resulting deferred is [cancelled][Job.cancel]. + * The resulting coroutine has a key difference compared with similar primitives in other languages + * and frameworks: it cancels the parent job (or outer scope) on failure to enforce *structured concurrency* paradigm. + * To change that behaviour, supervising parent ([SupervisorJob] or [supervisorScope]) can be used. * * Coroutine context is inherited from a [CoroutineScope], additional context elements can be specified with [context] argument. * If the context does not have any dispatcher nor any other [ContinuationInterceptor], then [Dispatchers.Default] is used. @@ -72,8 +75,6 @@ public fun CoroutineScope.launch( * the resulting [Deferred] is created in _new_ state. It can be explicitly started with [start][Job.start] * function and will be started implicitly on the first invocation of [join][Job.join], [await][Deferred.await] or [awaitAll]. * - * @param context additional to [CoroutineScope.coroutineContext] context of the coroutine. - * @param start coroutine start option. The default value is [CoroutineStart.DEFAULT]. * @param block the coroutine code. */ public fun CoroutineScope.async( diff --git a/kotlinx-coroutines-core/common/src/MainCoroutineDispatcher.kt b/kotlinx-coroutines-core/common/src/MainCoroutineDispatcher.kt index 3a73d239fd..2a20095aee 100644 --- a/kotlinx-coroutines-core/common/src/MainCoroutineDispatcher.kt +++ b/kotlinx-coroutines-core/common/src/MainCoroutineDispatcher.kt @@ -25,6 +25,9 @@ public abstract class MainCoroutineDispatcher : CoroutineDispatcher() { * /* * * If it is known that updateUiElement can be invoked both from the Main thread and from other threads, * * `immediate` dispatcher is used as a performance optimization to avoid unnecessary dispatch. + * * + * * In that case, when `updateUiElement` is invoked from the Main thread, `uiElement.text` will be + * * invoked immediately without any dispatching, otherwise, the `Dispatchers.Main` dispatch cycle will be triggered. * */ * withContext(Dispatchers.Main.immediate) { * uiElement.text = text diff --git a/kotlinx-coroutines-core/common/src/channels/Produce.kt b/kotlinx-coroutines-core/common/src/channels/Produce.kt index 8d34265f92..d7e01aba0b 100644 --- a/kotlinx-coroutines-core/common/src/channels/Produce.kt +++ b/kotlinx-coroutines-core/common/src/channels/Produce.kt @@ -100,8 +100,16 @@ public fun CoroutineScope.produce( } /** - * @suppress **This an internal API and should not be used from general code.** - * onCompletion parameter will be redesigned. + * This an internal API and should not be used from general code.** + * onCompletion parameter will be redesigned. + * If you have to use `onCompletion` operator, please report to https://github.com/Kotlin/kotlinx.coroutines/issues/. + * As a temporary solution, [invokeOnCompletion][Job.invokeOnCompletion] can be used instead: + * ``` + * fun ReceiveChannel.myOperator(): ReceiveChannel = GlobalScope.produce(Dispatchers.Unconfined) { + * coroutineContext[Job]?.invokeOnCompletion { consumes() } + * } + * ``` + * @suppress */ @InternalCoroutinesApi public fun CoroutineScope.produce( diff --git a/kotlinx-coroutines-core/native/README.md b/kotlinx-coroutines-core/native/README.md deleted file mode 100644 index a1bd39ed3a..0000000000 --- a/kotlinx-coroutines-core/native/README.md +++ /dev/null @@ -1,111 +0,0 @@ -# Module kotlinx-coroutines-core-native - -Core primitives to work with coroutines on Kotlin/Native. - -Coroutine builder functions: - -| **Name** | **Result** | **Scope** | **Description** -| ------------- | ------------- | ---------------- | --------------- -| [launch] | [Job] | [CoroutineScope] | Launches coroutine that does not have any result -| [async] | [Deferred] | [CoroutineScope] | Returns a single value with the future result -| [produce][kotlinx.coroutines.channels.produce] | [ReceiveChannel][kotlinx.coroutines.channels.ReceiveChannel] | [ProducerScope][kotlinx.coroutines.channels.ProducerScope] | Produces a stream of elements -| [runBlocking] | `T` | [CoroutineScope] | Blocks the thread while the coroutine runs - -Coroutine dispatchers implementing [CoroutineDispatcher]: - -| **Name** | **Description** -| --------------------------- | --------------- -| [Dispatchers.Default] | References current [runBlocking] event loop -| [Dispatchers.Unconfined] | Does not confine coroutine execution in any way - -More context elements: - -| **Name** | **Description** -| --------------------------- | --------------- -| [NonCancellable] | A non-cancelable job that is always active -| [CoroutineExceptionHandler] | Handler for uncaught exception - -Synchronization primitives for coroutines: - -| **Name** | **Suspending functions** | **Description** -| ---------- | ----------------------------------------------------------- | --------------- -| [Mutex][kotlinx.coroutines.sync.Mutex] | [lock][kotlinx.coroutines.sync.Mutex.lock] | Mutual exclusion -| [Channel][kotlinx.coroutines.channels.Channel] | [send][kotlinx.coroutines.channels.SendChannel.send], [receive][kotlinx.coroutines.channels.ReceiveChannel.receive] | Communication channel (aka queue or exchanger) - -Top-level suspending functions: - -| **Name** | **Description** -| ------------------- | --------------- -| [delay] | Non-blocking sleep -| [yield] | Yields thread in single-threaded dispatchers -| [withContext] | Switches to a different context -| [withTimeout] | Set execution time-limit with exception on timeout -| [withTimeoutOrNull] | Set execution time-limit will null result on timeout -| [awaitAll] | Awaits for successful completion of all given jobs or exceptional completion of any -| [joinAll] | Joins on all given jobs - -Cancellation support for user-defined suspending functions is available with [suspendCancellableCoroutine] -helper function. [NonCancellable] job object is provided to suppress cancellation with -`run(NonCancellable) {...}` block of code. - -[Select][kotlinx.coroutines.selects.select] expression waits for the result of multiple suspending functions simultaneously: - -| **Receiver** | **Suspending function** | **Select clause** | **Non-suspending version** -| ---------------- | --------------------------------------------- | ------------------------------------------------ | -------------------------- -| [Job] | [join][Job.join] | [onJoin][Job.onJoin] | [isCompleted][Job.isCompleted] -| [Deferred] | [await][Deferred.await] | [onAwait][Deferred.onAwait] | [isCompleted][Job.isCompleted] -| [SendChannel][kotlinx.coroutines.channels.SendChannel] | [send][kotlinx.coroutines.channels.SendChannel.send] | [onSend][kotlinx.coroutines.channels.SendChannel.onSend] | [offer][kotlinx.coroutines.channels.SendChannel.offer] -| [ReceiveChannel][kotlinx.coroutines.channels.ReceiveChannel] | [receive][kotlinx.coroutines.channels.ReceiveChannel.receive] | [onReceive][kotlinx.coroutines.channels.ReceiveChannel.onReceive] | [poll][kotlinx.coroutines.channels.ReceiveChannel.poll] -| [ReceiveChannel][kotlinx.coroutines.channels.ReceiveChannel] | [receiveOrNull][kotlinx.coroutines.channels.ReceiveChannel.receiveOrNull] | [onReceiveOrNull][kotlinx.coroutines.channels.ReceiveChannel.onReceiveOrNull] | [poll][kotlinx.coroutines.channels.ReceiveChannel.poll] -| [Mutex][kotlinx.coroutines.sync.Mutex] | [lock][kotlinx.coroutines.sync.Mutex.lock] | [onLock][kotlinx.coroutines.sync.Mutex.onLock] | [tryLock][kotlinx.coroutines.sync.Mutex.tryLock] -| none | [delay] | [onTimeout][kotlinx.coroutines.selects.SelectBuilder.onTimeout] | none - - - -[launch]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/launch.html -[Job]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-job/index.html -[CoroutineScope]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-scope/index.html -[async]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/async.html -[Deferred]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/index.html -[runBlocking]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/run-blocking.html -[CoroutineDispatcher]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-dispatcher/index.html -[Dispatchers.Default]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-dispatchers/-default.html -[Dispatchers.Unconfined]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-dispatchers/-unconfined.html -[NonCancellable]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-non-cancellable.html -[CoroutineExceptionHandler]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-exception-handler/index.html -[delay]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/delay.html -[yield]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/yield.html -[withContext]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/with-context.html -[withTimeout]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/with-timeout.html -[withTimeoutOrNull]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/with-timeout-or-null.html -[awaitAll]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/await-all.html -[joinAll]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/join-all.html -[suspendCancellableCoroutine]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/suspend-cancellable-coroutine.html -[Job.join]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-job/join.html -[Job.onJoin]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-job/on-join.html -[Job.isCompleted]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-job/is-completed.html -[Deferred.await]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/await.html -[Deferred.onAwait]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/on-await.html - -[kotlinx.coroutines.sync.Mutex]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.sync/-mutex/index.html -[kotlinx.coroutines.sync.Mutex.lock]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.sync/-mutex/lock.html -[kotlinx.coroutines.sync.Mutex.onLock]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.sync/-mutex/on-lock.html -[kotlinx.coroutines.sync.Mutex.tryLock]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.sync/-mutex/try-lock.html - -[kotlinx.coroutines.channels.produce]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/produce.html -[kotlinx.coroutines.channels.ReceiveChannel]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-receive-channel/index.html -[kotlinx.coroutines.channels.ProducerScope]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-producer-scope/index.html -[kotlinx.coroutines.channels.Channel]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-channel/index.html -[kotlinx.coroutines.channels.SendChannel.send]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-send-channel/send.html -[kotlinx.coroutines.channels.ReceiveChannel.receive]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-receive-channel/receive.html -[kotlinx.coroutines.channels.SendChannel]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-send-channel/index.html -[kotlinx.coroutines.channels.SendChannel.onSend]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-send-channel/on-send.html -[kotlinx.coroutines.channels.SendChannel.offer]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-send-channel/offer.html -[kotlinx.coroutines.channels.ReceiveChannel.onReceive]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-receive-channel/on-receive.html -[kotlinx.coroutines.channels.ReceiveChannel.poll]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-receive-channel/poll.html -[kotlinx.coroutines.channels.ReceiveChannel.receiveOrNull]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-receive-channel/receive-or-null.html -[kotlinx.coroutines.channels.ReceiveChannel.onReceiveOrNull]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-receive-channel/on-receive-or-null.html - -[kotlinx.coroutines.selects.select]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.selects/select.html -[kotlinx.coroutines.selects.SelectBuilder.onTimeout]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.selects/-select-builder/on-timeout.html - diff --git a/kotlinx-coroutines-test/src/TestCoroutineExceptionHandler.kt b/kotlinx-coroutines-test/src/TestCoroutineExceptionHandler.kt index a2e9d51b96..41d14d0841 100644 --- a/kotlinx-coroutines-test/src/TestCoroutineExceptionHandler.kt +++ b/kotlinx-coroutines-test/src/TestCoroutineExceptionHandler.kt @@ -40,6 +40,7 @@ public class TestCoroutineExceptionHandler : { private val _exceptions = mutableListOf() + /** @suppress **/ override fun handleException(context: CoroutineContext, exception: Throwable) { synchronized(_exceptions) { _exceptions += exception diff --git a/ui/kotlinx-coroutines-android/src/HandlerDispatcher.kt b/ui/kotlinx-coroutines-android/src/HandlerDispatcher.kt index fb0ee47684..f656b353c5 100644 --- a/ui/kotlinx-coroutines-android/src/HandlerDispatcher.kt +++ b/ui/kotlinx-coroutines-android/src/HandlerDispatcher.kt @@ -34,6 +34,10 @@ public sealed class HandlerDispatcher : MainCoroutineDispatcher(), Delay { * /* * * If it is known that updateUiElement can be invoked both from the Main thread and from other threads, * * `immediate` dispatcher is used as a performance optimization to avoid unnecessary dispatch. + * * + * * In that case, when `updateUiElement` is invoked from the Main thread, `uiElement.text` will be + * * invoked immediately without any dispatching, otherwise, the `Dispatchers.Main` dispatch cycle via + * * `Handler.post` will be triggered. * */ * withContext(Dispatchers.Main.immediate) { * uiElement.text = text