Skip to content

Commit a7e1014

Browse files
committed
Merge branch 'release-candidate' into develop
# Conflicts: # core/kotlinx-coroutines-core/test/RunBlockingTest.kt # docs/coroutine-context-and-dispatchers.md
2 parents 46cc6aa + e44c9b2 commit a7e1014

File tree

576 files changed

+3772
-5855
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

576 files changed

+3772
-5855
lines changed

CHANGES.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,9 @@ Visible consequences of include more robust exception handling for large corouti
7474
* All coroutine builders are now extensions on `CoroutineScope` and inherit its `coroutineContext`. Standalone builders are deprecated.
7575
* As a consequence, all nested coroutines launched via builders now automatically establish parent-child relationship and inherit `CoroutineDispatcher`.
7676
* All coroutine builders use `Dispatchers.Default` by default if `CoroutineInterceptor` is not present in their context.
77-
* [CoroutineScope](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-coroutine-scope/) became the first-class citizen in `kolinx.coroutines`.
77+
* [CoroutineScope](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-scope/) became the first-class citizen in `kolinx.coroutines`.
7878
* `withContext` `block` argument has `CoroutineScope` as a receiver.
79-
* [GlobalScope](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-global-scope/) is introduced to simplify migration to new API and to launch global-level coroutines.
79+
* [GlobalScope](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-global-scope/) is introduced to simplify migration to new API and to launch global-level coroutines.
8080
* `currentScope` and `coroutineScope` builders are introduced to extract and provide `CoroutineScope`.
8181
* Factory methods to create `CoroutineScope` from `CoroutineContext` are introduced.
8282
* `CoroutineScope.isActive` became an extension property.
@@ -604,7 +604,7 @@ Visible consequences of include more robust exception handling for large corouti
604604
## Version 0.11-rc
605605

606606
* `select` expression with onJoin/onAwait/onSend/onReceive clauses.
607-
* `Mutex` is moved to `kotlinx.coroutines.experimental.sync` package.
607+
* `Mutex` is moved to `kotlinx.coroutines.sync` package.
608608
* `ClosedSendChannelException` is a subclass of `CancellationException` now.
609609
* New sections on "Shared mutable state and concurrency" and "Select expression"
610610
in [coroutines guide](docs/coroutines-guide.md).

README.md

+11-17
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
[![Download](https://api.bintray.com/packages/kotlin/kotlinx/kotlinx.coroutines/images/download.svg?version=0.30.2) ](https://bintray.com/kotlin/kotlinx/kotlinx.coroutines/0.30.2)
66

77
Library support for Kotlin coroutines with [multiplatform](#multiplatform) support.
8-
This is a companion version for Kotlin 1.2.70 release.
8+
This is a companion version for Kotlin 1.3.0-rc-146 release.
99

1010
**NOTE**: This is the _last_ experimental feature release.
1111
See [COMPATIBILITY.md](COMPATIBILITY.md) for details of migration onto the stable Kotlin 1.3 coroutines.
@@ -70,33 +70,35 @@ Add dependencies (you can also add other modules that you need):
7070
<dependency>
7171
<groupId>org.jetbrains.kotlinx</groupId>
7272
<artifactId>kotlinx-coroutines-core</artifactId>
73-
<version>0.30.2</version>
73+
<version>0.30.2-eap13</version>
7474
</dependency>
7575
```
7676

7777
And make sure that you use the latest Kotlin version:
7878

7979
```xml
8080
<properties>
81-
<kotlin.version>1.2.70</kotlin.version>
81+
<kotlin.version>1.3.0-rc-146</kotlin.version>
8282
</properties>
8383
```
8484

85+
While Kotlin 1.3 is still in release candidate status, in order to depend on it you should add eap repository: `https://dl.bintray.com/kotlin/kotlin-eap`.
86+
8587
### Gradle
8688

8789
Add dependencies (you can also add other modules that you need):
8890

8991
```groovy
9092
dependencies {
91-
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.30.2'
93+
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.30.2-eap13'
9294
}
9395
```
9496

9597
And make sure that you use the latest Kotlin version:
9698

9799
```groovy
98100
buildscript {
99-
ext.kotlin_version = '1.2.70'
101+
ext.kotlin_version = '1.3.0-rc-146'
100102
}
101103
```
102104

@@ -148,24 +150,16 @@ Add [`kotlinx-coroutines-android`](ui/kotlinx-coroutines-android)
148150
module as dependency when using `kotlinx.coroutines` on Android:
149151

150152
```groovy
151-
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:0.30.2'
153+
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:0.30.2-eap13'
152154
```
153-
This gives you access to Android [Dispatchers.Main](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-android/kotlinx.coroutines.experimental.android/kotlinx.coroutines.experimental.-dispatchers/index.html)
155+
This gives you access to Android [Dispatchers.Main](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-android/kotlinx.coroutines.android/kotlinx.coroutines.-dispatchers/index.html)
154156
coroutine dispatcher and also makes sure that in case of crashed coroutine with unhandled exception this
155157
exception is logged before crashing Android application, similarly to the way uncaught exceptions in
156158
threads are handled by Android runtime.
157159

158-
### ProGuard
159-
160-
In obfuscated code, fields with different types can have the same names,
161-
and `AtomicReferenceFieldUpdater` may be unable to find the correct ones.
162-
To avoid field overloading by type during obfuscation, add this to your config:
160+
### R8 and ProGuard
163161

164-
```
165-
-keepclassmembernames class kotlinx.** {
166-
volatile <fields>;
167-
}
168-
```
162+
If you are using R8 or ProGuard add the options from [coroutines.pro](core/kotlinx-coroutines-core/resources/META-INF/proguard/coroutines.pro) file to your rules.
169163

170164
## Building
171165

benchmarks/src/jmh/kotlin/benchmarks/CancellableContinuationBenchmark.kt

+4-7
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44

55
package benchmarks
66

7-
import kotlinx.coroutines.experimental.*
7+
import kotlinx.coroutines.*
88
import org.openjdk.jmh.annotations.*
99
import java.util.concurrent.*
10-
import kotlin.coroutines.experimental.*
11-
import kotlin.coroutines.experimental.intrinsics.*
10+
import kotlin.coroutines.*
11+
import kotlin.coroutines.intrinsics.*
1212

1313
@Warmup(iterations = 5)
1414
@Measurement(iterations = 10)
@@ -47,10 +47,7 @@ open class CancellableContinuationBenchmark {
4747
override val context: CoroutineContext
4848
get() = EmptyCoroutineContext
4949

50-
override fun resume(value: Int) {
51-
}
52-
53-
override fun resumeWithException(exception: Throwable) {
50+
override fun resumeWith(result: Result<Int>) {
5451
}
5552
}
5653
}

benchmarks/src/jmh/kotlin/benchmarks/ChannelSinkBenchmark.kt

+30-10
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,49 @@
44

55
package benchmarks
66

7-
import kotlinx.coroutines.experimental.*
8-
import kotlinx.coroutines.experimental.channels.*
7+
import kotlinx.coroutines.*
8+
import kotlinx.coroutines.channels.*
99
import org.openjdk.jmh.annotations.*
1010
import java.util.concurrent.*
11-
import kotlin.coroutines.experimental.*
11+
import kotlin.coroutines.*
1212

13-
@Warmup(iterations = 10, time = 1)
14-
@Measurement(iterations = 10, time = 1)
13+
@Warmup(iterations = 5, time = 1)
14+
@Measurement(iterations = 5, time = 1)
1515
@BenchmarkMode(Mode.AverageTime)
1616
@OutputTimeUnit(TimeUnit.MILLISECONDS)
1717
@State(Scope.Benchmark)
18-
@Fork(2)
18+
@Fork(1)
1919
open class ChannelSinkBenchmark {
20+
private val tl = ThreadLocal.withInitial({ 42 })
21+
private val tl2 = ThreadLocal.withInitial({ 239 })
22+
23+
private val unconfined = Dispatchers.Unconfined
24+
private val unconfinedOneElement = Dispatchers.Unconfined + tl.asContextElement()
25+
private val unconfinedTwoElements = Dispatchers.Unconfined + tl.asContextElement() + tl2.asContextElement()
2026

2127
@Benchmark
2228
fun channelPipeline(): Int = runBlocking {
23-
Channel
24-
.range(1, 1_000_000, Unconfined)
25-
.filter(Unconfined) { it % 4 == 0 }
29+
run(unconfined)
30+
}
31+
32+
@Benchmark
33+
fun channelPipelineOneThreadLocal(): Int = runBlocking {
34+
run(unconfinedOneElement)
35+
}
36+
37+
@Benchmark
38+
fun channelPipelineTwoThreadLocals(): Int = runBlocking {
39+
run(unconfinedTwoElements)
40+
}
41+
42+
private suspend inline fun run(context: CoroutineContext): Int {
43+
return Channel
44+
.range(1, 1_000_000, context)
45+
.filter(context) { it % 4 == 0 }
2646
.fold(0) { a, b -> a + b }
2747
}
2848

29-
private fun Channel.Factory.range(start: Int, count: Int, context: CoroutineContext) = produce(context) {
49+
private fun Channel.Factory.range(start: Int, count: Int, context: CoroutineContext) = GlobalScope.produce(context) {
3050
for (i in start until (start + count))
3151
send(i)
3252
}

benchmarks/src/jmh/kotlin/benchmarks/ForkJoinBenchmark.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
package benchmarks
66

7-
import kotlinx.coroutines.experimental.*
7+
import kotlinx.coroutines.*
88
import org.openjdk.jmh.annotations.*
99
import java.util.concurrent.*
1010

@@ -54,7 +54,7 @@ open class ForkJoinBenchmark : ParametrizedDispatcherBase() {
5454

5555
@Benchmark
5656
fun asyncFjp() = runBlocking {
57-
CoroutineScope(CommonPool).startAsync(coefficients, 0, coefficients.size).await()
57+
CoroutineScope(ForkJoinPool.commonPool().asCoroutineDispatcher()).startAsync(coefficients, 0, coefficients.size).await()
5858
}
5959

6060
@Benchmark

benchmarks/src/jmh/kotlin/benchmarks/LaunchBenchmark.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
package benchmarks
66

7-
import kotlinx.coroutines.experimental.*
7+
import kotlinx.coroutines.*
88
import org.openjdk.jmh.annotations.*
99
import java.util.concurrent.*
1010

benchmarks/src/jmh/kotlin/benchmarks/ParametrizedDispatcherBase.kt

+6-4
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55
package benchmarks
66

77
import benchmarks.actors.CORES_COUNT
8-
import kotlinx.coroutines.experimental.*
9-
import kotlinx.coroutines.experimental.scheduling.*
8+
import kotlinx.coroutines.*
9+
import kotlinx.coroutines.scheduling.*
1010
import org.openjdk.jmh.annotations.Param
1111
import org.openjdk.jmh.annotations.Setup
1212
import org.openjdk.jmh.annotations.TearDown
1313
import java.io.Closeable
14-
import kotlin.coroutines.experimental.CoroutineContext
14+
import java.util.concurrent.*
15+
import kotlin.coroutines.CoroutineContext
1516

1617
/**
1718
* Base class to use different [CoroutineContext] in benchmarks via [Param] in inheritors.
@@ -23,10 +24,11 @@ abstract class ParametrizedDispatcherBase : CoroutineScope {
2324
override lateinit var coroutineContext: CoroutineContext
2425
var closeable: Closeable? = null
2526

27+
@UseExperimental(InternalCoroutinesApi::class)
2628
@Setup
2729
open fun setup() {
2830
coroutineContext = when {
29-
dispatcher == "fjp" -> CommonPool
31+
dispatcher == "fjp" -> ForkJoinPool.commonPool().asCoroutineDispatcher()
3032
dispatcher == "experimental" -> {
3133
ExperimentalCoroutineDispatcher(CORES_COUNT).also { closeable = it }
3234
}

benchmarks/src/jmh/kotlin/benchmarks/StatefulAwaitsBenchmark.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
package benchmarks
66

7-
import kotlinx.coroutines.experimental.*
8-
import kotlinx.coroutines.experimental.channels.*
7+
import kotlinx.coroutines.*
8+
import kotlinx.coroutines.channels.*
99
import org.openjdk.jmh.annotations.*
1010
import java.util.concurrent.*
1111

benchmarks/src/jmh/kotlin/benchmarks/actors/ConcurrentStatefulActorBenchmark.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ package benchmarks.actors
66

77
import benchmarks.*
88
import benchmarks.actors.StatefulActorBenchmark.*
9-
import kotlinx.coroutines.experimental.*
10-
import kotlinx.coroutines.experimental.channels.*
9+
import kotlinx.coroutines.*
10+
import kotlinx.coroutines.channels.*
1111
import org.openjdk.jmh.annotations.*
1212
import java.util.concurrent.*
1313

benchmarks/src/jmh/kotlin/benchmarks/actors/CycledActorsBenchmark.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ package benchmarks.actors
66

77
import benchmarks.*
88
import benchmarks.actors.PingPongActorBenchmark.*
9-
import kotlinx.coroutines.experimental.*
10-
import kotlinx.coroutines.experimental.channels.*
9+
import kotlinx.coroutines.*
10+
import kotlinx.coroutines.channels.*
1111
import org.openjdk.jmh.annotations.*
1212
import java.util.concurrent.*
1313

benchmarks/src/jmh/kotlin/benchmarks/actors/PingPongActorBenchmark.kt

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
package benchmarks.actors
66

77
import benchmarks.*
8-
import kotlinx.coroutines.experimental.*
9-
import kotlinx.coroutines.experimental.channels.*
8+
import kotlinx.coroutines.*
9+
import kotlinx.coroutines.channels.*
1010
import org.openjdk.jmh.annotations.*
1111
import java.util.concurrent.*
12-
import kotlin.coroutines.experimental.*
12+
import kotlin.coroutines.*
1313

1414
/*
1515
* Benchmark (dispatcher) Mode Cnt Score Error Units

benchmarks/src/jmh/kotlin/benchmarks/actors/PingPongWithBlockingContext.kt

+9-7
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44

55
package benchmarks.actors
66

7-
import kotlinx.coroutines.experimental.*
8-
import kotlinx.coroutines.experimental.channels.*
9-
import kotlinx.coroutines.experimental.scheduling.*
7+
import kotlinx.coroutines.*
8+
import kotlinx.coroutines.channels.*
9+
import kotlinx.coroutines.scheduling.*
1010
import org.openjdk.jmh.annotations.*
1111
import java.util.concurrent.*
12-
import kotlin.coroutines.experimental.*
12+
import kotlin.coroutines.*
1313

1414

1515
/*
@@ -26,7 +26,9 @@ import kotlin.coroutines.experimental.*
2626
@State(Scope.Benchmark)
2727
open class PingPongWithBlockingContext {
2828

29+
@UseExperimental(InternalCoroutinesApi::class)
2930
private val experimental = ExperimentalCoroutineDispatcher(8)
31+
@UseExperimental(InternalCoroutinesApi::class)
3032
private val blocking = experimental.blocking(8)
3133
private val threadPool = newFixedThreadPoolContext(8, "PongCtx")
3234

@@ -49,13 +51,13 @@ open class PingPongWithBlockingContext {
4951

5052
@Benchmark
5153
fun commonPoolWithContextPingPong() = runBlocking {
52-
runPingPongs(CommonPool, threadPool)
54+
runPingPongs(ForkJoinPool.commonPool().asCoroutineDispatcher(), threadPool)
5355
}
5456

5557
private suspend fun runPingPongs(pingContext: CoroutineContext, pongContext: CoroutineContext) {
5658
val me = Channel<PingPongActorBenchmark.Letter>()
57-
val pong = pongActorCoroutine(pongContext)
58-
val ping = pingActorCoroutine(pingContext, pong)
59+
val pong = CoroutineScope(pongContext).pongActorCoroutine()
60+
val ping = CoroutineScope(pingContext).pingActorCoroutine(pong)
5961
ping.send(PingPongActorBenchmark.Letter(Start(), me))
6062

6163
me.receive()

benchmarks/src/jmh/kotlin/benchmarks/actors/StatefulActorBenchmark.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
package benchmarks.actors
66

77
import benchmarks.*
8-
import kotlinx.coroutines.experimental.*
9-
import kotlinx.coroutines.experimental.channels.*
8+
import kotlinx.coroutines.*
9+
import kotlinx.coroutines.channels.*
1010
import org.openjdk.jmh.annotations.*
1111
import java.util.concurrent.*
1212

Original file line numberDiff line numberDiff line change
@@ -1,38 +1,13 @@
1-
public final class kotlinx/coroutines/experimental/android/HandlerContext : kotlinx/coroutines/experimental/android/HandlerDispatcher, kotlinx/coroutines/experimental/Delay {
2-
public fun <init> (Landroid/os/Handler;Ljava/lang/String;)V
3-
public synthetic fun <init> (Landroid/os/Handler;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
4-
public final fun awaitFrame (Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object;
5-
public fun dispatch (Lkotlin/coroutines/experimental/CoroutineContext;Ljava/lang/Runnable;)V
6-
public fun equals (Ljava/lang/Object;)Z
7-
public synthetic fun getImmediate ()Lkotlinx/coroutines/experimental/MainCoroutineDispatcher;
8-
public fun getImmediate ()Lkotlinx/coroutines/experimental/android/HandlerContext;
9-
public synthetic fun getImmediate ()Lkotlinx/coroutines/experimental/android/HandlerDispatcher;
10-
public fun hashCode ()I
11-
public fun invokeOnTimeout (JLjava/lang/Runnable;)Lkotlinx/coroutines/experimental/DisposableHandle;
12-
public fun isDispatchNeeded (Lkotlin/coroutines/experimental/CoroutineContext;)Z
13-
public fun scheduleResumeAfterDelay (JLkotlinx/coroutines/experimental/CancellableContinuation;)V
14-
public fun toString ()Ljava/lang/String;
1+
public abstract class kotlinx/coroutines/android/HandlerDispatcher : kotlinx/coroutines/MainCoroutineDispatcher, kotlinx/coroutines/Delay {
2+
public fun delay (JLkotlin/coroutines/Continuation;)Ljava/lang/Object;
3+
public abstract fun getImmediate ()Lkotlinx/coroutines/android/HandlerDispatcher;
4+
public fun invokeOnTimeout (JLjava/lang/Runnable;)Lkotlinx/coroutines/DisposableHandle;
155
}
166

17-
public final class kotlinx/coroutines/experimental/android/HandlerContextKt {
18-
public static final synthetic fun asCoroutineDispatcher (Landroid/os/Handler;)Lkotlinx/coroutines/experimental/android/HandlerContext;
19-
public static final fun getUI ()Lkotlinx/coroutines/experimental/android/HandlerContext;
20-
}
21-
22-
public abstract class kotlinx/coroutines/experimental/android/HandlerDispatcher : kotlinx/coroutines/experimental/MainCoroutineDispatcher, kotlinx/coroutines/experimental/Delay {
23-
public synthetic fun delay (JLjava/util/concurrent/TimeUnit;Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object;
24-
public fun delay (JLkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object;
25-
public abstract fun getImmediate ()Lkotlinx/coroutines/experimental/android/HandlerDispatcher;
26-
public fun invokeOnTimeout (JLjava/lang/Runnable;)Lkotlinx/coroutines/experimental/DisposableHandle;
27-
public synthetic fun invokeOnTimeout (JLjava/util/concurrent/TimeUnit;Ljava/lang/Runnable;)Lkotlinx/coroutines/experimental/DisposableHandle;
28-
public synthetic fun scheduleResumeAfterDelay (JLjava/util/concurrent/TimeUnit;Lkotlinx/coroutines/experimental/CancellableContinuation;)V
29-
}
30-
31-
public final class kotlinx/coroutines/experimental/android/HandlerDispatcherKt {
32-
public static final fun awaitFrame (Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object;
33-
public static final fun from (Landroid/os/Handler;)Lkotlinx/coroutines/experimental/android/HandlerDispatcher;
34-
public static final fun from (Landroid/os/Handler;Ljava/lang/String;)Lkotlinx/coroutines/experimental/android/HandlerDispatcher;
35-
public static synthetic fun from$default (Landroid/os/Handler;Ljava/lang/String;ILjava/lang/Object;)Lkotlinx/coroutines/experimental/android/HandlerDispatcher;
36-
public static final synthetic fun getMain (Lkotlinx/coroutines/experimental/Dispatchers;)Lkotlinx/coroutines/experimental/android/HandlerDispatcher;
7+
public final class kotlinx/coroutines/android/HandlerDispatcherKt {
8+
public static final fun awaitFrame (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
9+
public static final fun from (Landroid/os/Handler;)Lkotlinx/coroutines/android/HandlerDispatcher;
10+
public static final fun from (Landroid/os/Handler;Ljava/lang/String;)Lkotlinx/coroutines/android/HandlerDispatcher;
11+
public static synthetic fun from$default (Landroid/os/Handler;Ljava/lang/String;ILjava/lang/Object;)Lkotlinx/coroutines/android/HandlerDispatcher;
3712
}
3813

0 commit comments

Comments
 (0)