Skip to content

Commit c65071c

Browse files
elizarovqwwdfsad
authored andcommitted
Structured concurrency for guava, jdk8 and promise modules, proper reference to newCoroutineContext
1 parent ac466ec commit c65071c

File tree

28 files changed

+226
-140
lines changed

28 files changed

+226
-140
lines changed

binary-compatibility-validator/reference-public-api/kotlinx-coroutines-core.txt

+1
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ public final class kotlinx/coroutines/experimental/CoroutineContextKt {
144144
public static final fun getIO ()Lkotlinx/coroutines/experimental/CoroutineDispatcher;
145145
public static final fun newCoroutineContext (Lkotlin/coroutines/experimental/CoroutineContext;)Lkotlin/coroutines/experimental/CoroutineContext;
146146
public static final fun newCoroutineContext (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/Job;)Lkotlin/coroutines/experimental/CoroutineContext;
147+
public static final fun newCoroutineContext (Lkotlinx/coroutines/experimental/CoroutineScope;Lkotlin/coroutines/experimental/CoroutineContext;)Lkotlin/coroutines/experimental/CoroutineContext;
147148
public static synthetic fun newCoroutineContext$default (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/Job;ILjava/lang/Object;)Lkotlin/coroutines/experimental/CoroutineContext;
148149
}
149150

Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
public final class kotlinx/coroutines/experimental/guava/ListenableFutureKt {
22
public static final fun asListenableFuture (Lkotlinx/coroutines/experimental/Deferred;)Lcom/google/common/util/concurrent/ListenableFuture;
33
public static final fun await (Lcom/google/common/util/concurrent/ListenableFuture;Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object;
4+
public static final fun future (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)Lcom/google/common/util/concurrent/ListenableFuture;
45
public static final synthetic fun future (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlin/jvm/functions/Function2;)Lcom/google/common/util/concurrent/ListenableFuture;
56
public static final fun future (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlinx/coroutines/experimental/Job;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)Lcom/google/common/util/concurrent/ListenableFuture;
67
public static final synthetic fun future (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlinx/coroutines/experimental/Job;Lkotlin/jvm/functions/Function2;)Lcom/google/common/util/concurrent/ListenableFuture;
8+
public static final fun future (Lkotlinx/coroutines/experimental/CoroutineScope;Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)Lcom/google/common/util/concurrent/ListenableFuture;
9+
public static synthetic fun future$default (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/google/common/util/concurrent/ListenableFuture;
710
public static synthetic fun future$default (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/google/common/util/concurrent/ListenableFuture;
811
public static synthetic fun future$default (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlinx/coroutines/experimental/Job;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/google/common/util/concurrent/ListenableFuture;
912
public static synthetic fun future$default (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlinx/coroutines/experimental/Job;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/google/common/util/concurrent/ListenableFuture;
13+
public static synthetic fun future$default (Lkotlinx/coroutines/experimental/CoroutineScope;Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/google/common/util/concurrent/ListenableFuture;
1014
}
1115

binary-compatibility-validator/reference-public-api/kotlinx-coroutines-jdk8.txt

+4
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,17 @@ public final class kotlinx/coroutines/experimental/future/FutureKt {
1111
public static final synthetic fun await (Ljava/util/concurrent/CompletableFuture;Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object;
1212
public static final fun await (Ljava/util/concurrent/CompletionStage;Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object;
1313
public static final synthetic fun future (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlin/jvm/functions/Function1;)Ljava/util/concurrent/CompletableFuture;
14+
public static final fun future (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)Ljava/util/concurrent/CompletableFuture;
1415
public static final synthetic fun future (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlin/jvm/functions/Function2;)Ljava/util/concurrent/CompletableFuture;
1516
public static final fun future (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlinx/coroutines/experimental/Job;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)Ljava/util/concurrent/CompletableFuture;
1617
public static final synthetic fun future (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlinx/coroutines/experimental/Job;Lkotlin/jvm/functions/Function2;)Ljava/util/concurrent/CompletableFuture;
18+
public static final fun future (Lkotlinx/coroutines/experimental/CoroutineScope;Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)Ljava/util/concurrent/CompletableFuture;
1719
public static synthetic fun future$default (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/util/concurrent/CompletableFuture;
20+
public static synthetic fun future$default (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Ljava/util/concurrent/CompletableFuture;
1821
public static synthetic fun future$default (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Ljava/util/concurrent/CompletableFuture;
1922
public static synthetic fun future$default (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlinx/coroutines/experimental/Job;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Ljava/util/concurrent/CompletableFuture;
2023
public static synthetic fun future$default (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlinx/coroutines/experimental/Job;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Ljava/util/concurrent/CompletableFuture;
24+
public static synthetic fun future$default (Lkotlinx/coroutines/experimental/CoroutineScope;Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Ljava/util/concurrent/CompletableFuture;
2125
public static final fun toCompletableFuture (Lkotlinx/coroutines/experimental/Deferred;)Ljava/util/concurrent/CompletableFuture;
2226
}
2327

common/kotlinx-coroutines-core-common/src/CoroutineContext.common.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ package kotlinx.coroutines.experimental
66

77
import kotlin.coroutines.experimental.*
88

9-
public expect fun newCoroutineContext(context: CoroutineContext, parent: Job? = null): CoroutineContext
9+
public expect fun CoroutineScope.newCoroutineContext(context: CoroutineContext): CoroutineContext
1010

1111
@Suppress("PropertyName")
1212
public expect val DefaultDispatcher: CoroutineDispatcher

common/kotlinx-coroutines-core-common/src/Deferred.kt

-2
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,7 @@ public interface Deferred<out T> : Job {
125125

126126
/**
127127
* Creates new coroutine and returns its future result as an implementation of [Deferred].
128-
*
129128
* The running coroutine is cancelled when the resulting deferred is [cancelled][Job.cancel].
130-
* Parent of the created coroutine is inherited from the provided [CoroutineScope].
131129
*
132130
* Coroutine context is inherited from a [CoroutineScope], additional context elements can be specified with [context] argument.
133131
* If the context does not have any dispatcher nor any other [ContinuationInterceptor], then [DefaultDispatcher] is used.

common/kotlinx-coroutines-core-common/src/channels/Broadcast.kt

+9-14
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ package kotlinx.coroutines.experimental.channels
77
import kotlinx.coroutines.experimental.*
88
import kotlinx.coroutines.experimental.channels.Channel.Factory.CONFLATED
99
import kotlinx.coroutines.experimental.channels.Channel.Factory.UNLIMITED
10-
import kotlinx.coroutines.experimental.internal.*
1110
import kotlinx.coroutines.experimental.intrinsics.*
1211
import kotlin.coroutines.experimental.*
1312

@@ -21,34 +20,30 @@ fun <E> ReceiveChannel<E>.broadcast(
2120
capacity: Int = 1,
2221
start: CoroutineStart = CoroutineStart.LAZY
2322
) : BroadcastChannel<E> =
24-
broadcast(Unconfined, capacity = capacity, start = start, onCompletion = consumes()) {
23+
GlobalScope.broadcast(Unconfined, capacity = capacity, start = start, onCompletion = consumes()) {
2524
for (e in this@broadcast) {
2625
send(e)
2726
}
2827
}
2928

3029
/**
3130
* Launches new coroutine to produce a stream of values by sending them to a broadcast channel.
32-
* Deprecated, use [CoroutineScope.broadcast] instead.
31+
* @suppress **Deprecated**: use [CoroutineScope.broadcast] instead.
3332
*/
34-
@Deprecated(message = "Standalone coroutine builders are deprecated, use extensions on CoroutineScope instead. This API will be hidden in the next release")
33+
@Deprecated(
34+
message = "Standalone coroutine builders are deprecated, use extensions on CoroutineScope instead",
35+
replaceWith = ReplaceWith("GlobalScope.broadcast(context + parent, capacity, start, onCompletion, block)",
36+
imports = ["kotlinx.coroutines.experimental.GlobalScope", "kotlinx.coroutines.experimental.channels.broadcast"])
37+
)
3538
public fun <E> broadcast(
3639
context: CoroutineContext = DefaultDispatcher,
3740
capacity: Int = 1,
3841
start: CoroutineStart = CoroutineStart.LAZY,
3942
parent: Job? = null,
4043
onCompletion: CompletionHandler? = null,
4144
block: suspend ProducerScope<E>.() -> Unit
42-
): BroadcastChannel<E> {
43-
val channel = BroadcastChannel<E>(capacity)
44-
val newContext = newCoroutineContext(context, parent)
45-
val coroutine = if (start.isLazy)
46-
LazyBroadcastCoroutine(newContext, channel, block) else
47-
BroadcastCoroutine(newContext, channel, active = true)
48-
if (onCompletion != null) coroutine.invokeOnCompletion(handler = onCompletion)
49-
coroutine.start(start, coroutine, block)
50-
return coroutine
51-
}
45+
): BroadcastChannel<E> =
46+
GlobalScope.broadcast(context + (parent ?: DefaultDispatcher), capacity, start, onCompletion, block)
5247

5348
/**
5449
* Launches new coroutine to produce a stream of values by sending them to a broadcast channel

common/kotlinx-coroutines-core-common/src/internal/Scopes.kt

-3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,3 @@ internal class ScopeOwnerCoroutine<R>(
2525
internal class ContextScope(context: CoroutineContext) : CoroutineScope {
2626
override val coroutineContext: CoroutineContext = context
2727
}
28-
29-
internal fun CoroutineScope.newCoroutineContext(context: CoroutineContext): CoroutineContext =
30-
newCoroutineContext(coroutineContext + context, parent = null)

core/kotlinx-coroutines-core/src/Builders.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import kotlin.coroutines.experimental.*
2727
* If this blocked thread is interrupted (see [Thread.interrupt]), then the coroutine job is cancelled and
2828
* this `runBlocking` invocation throws [InterruptedException].
2929
*
30-
* See [newCoroutineContext] for a description of debugging facilities that are available for newly created coroutine.
30+
* See [newCoroutineContext][CoroutineScope.newCoroutineContext] for a description of debugging facilities that are available for newly created coroutine.
3131
*
3232
* @param context context of the coroutine. The default value is an implementation of [EventLoop].
3333
* @param block the coroutine code.
@@ -38,7 +38,7 @@ public fun <T> runBlocking(context: CoroutineContext = EmptyCoroutineContext, bl
3838
val contextInterceptor = context[ContinuationInterceptor]
3939
val privateEventLoop = contextInterceptor == null // create private event loop if no dispatcher is specified
4040
val eventLoop = if (privateEventLoop) BlockingEventLoop(currentThread) else contextInterceptor as? EventLoop
41-
val newContext = newCoroutineContext(
41+
val newContext = GlobalScope.newCoroutineContext(
4242
if (privateEventLoop) context + (eventLoop as ContinuationInterceptor) else context
4343
)
4444
val coroutine = BlockingCoroutine<T>(newContext, currentThread, eventLoop, privateEventLoop)

core/kotlinx-coroutines-core/src/CoroutineContext.kt

+20-10
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,22 @@ import java.util.concurrent.atomic.*
1010
import kotlin.coroutines.experimental.*
1111

1212
/**
13-
* Name of the property that controls coroutine debugging. See [newCoroutineContext].
13+
* Name of the property that controls coroutine debugging. See [newCoroutineContext][CoroutineScope.newCoroutineContext].
1414
*/
1515
public const val DEBUG_PROPERTY_NAME = "kotlinx.coroutines.debug"
1616

1717
/**
18-
* Automatic debug configuration value for [DEBUG_PROPERTY_NAME]. See [newCoroutineContext].
18+
* Automatic debug configuration value for [DEBUG_PROPERTY_NAME]. See [newCoroutineContext][CoroutineScope.newCoroutineContext].
1919
*/
2020
public const val DEBUG_PROPERTY_VALUE_AUTO = "auto"
2121

2222
/**
23-
* Debug turned on value for [DEBUG_PROPERTY_NAME]. See [newCoroutineContext].
23+
* Debug turned on value for [DEBUG_PROPERTY_NAME]. See [newCoroutineContext][CoroutineScope.newCoroutineContext].
2424
*/
2525
public const val DEBUG_PROPERTY_VALUE_ON = "on"
2626

2727
/**
28-
* Debug turned on value for [DEBUG_PROPERTY_NAME]. See [newCoroutineContext].
28+
* Debug turned on value for [DEBUG_PROPERTY_NAME]. See [newCoroutineContext][CoroutineScope.newCoroutineContext].
2929
*/
3030
public const val DEBUG_PROPERTY_VALUE_OFF = "off"
3131

@@ -106,14 +106,24 @@ public val IO: CoroutineDispatcher by lazy {
106106
* Coroutine name can be explicitly assigned using [CoroutineName] context element.
107107
* The string "coroutine" is used as a default name.
108108
*/
109+
public actual fun CoroutineScope.newCoroutineContext(context: CoroutineContext): CoroutineContext {
110+
val combined = coroutineContext + context
111+
val debug = if (DEBUG) combined + CoroutineId(COROUTINE_ID.incrementAndGet()) else combined
112+
return if (combined !== DefaultDispatcher && combined[ContinuationInterceptor] == null)
113+
debug + DefaultDispatcher else debug
114+
}
115+
116+
/**
117+
* @suppress **Deprecated**: Use extension on CoroutineScope.
118+
*/
109119
@JvmOverloads // for binary compatibility with newCoroutineContext(context: CoroutineContext) version
110120
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
111-
public actual fun newCoroutineContext(context: CoroutineContext, parent: Job? = null): CoroutineContext {
112-
val debug = if (DEBUG) context + CoroutineId(COROUTINE_ID.incrementAndGet()) else context
113-
val wp = if (parent == null) debug else debug + parent
114-
return if (context !== DefaultDispatcher && context[ContinuationInterceptor] == null)
115-
wp + DefaultDispatcher else wp
116-
}
121+
@Deprecated(
122+
message = "Use extension on CoroutineScope",
123+
replaceWith = ReplaceWith("GlobalScope.newCoroutineContext(context + parent)")
124+
)
125+
public fun newCoroutineContext(context: CoroutineContext, parent: Job? = null): CoroutineContext =
126+
GlobalScope.newCoroutineContext(context + (parent ?: EmptyCoroutineContext))
117127

118128
/**
119129
* Executes a block using a given coroutine context.

core/kotlinx-coroutines-core/src/CoroutineName.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import kotlin.coroutines.experimental.CoroutineContext
99

1010
/**
1111
* User-specified name of coroutine. This name is used in debugging mode.
12-
* See [newCoroutineContext] for the description of coroutine debugging facilities.
12+
* See [newCoroutineContext][CoroutineScope.newCoroutineContext] for the description of coroutine debugging facilities.
1313
*/
1414
public data class CoroutineName(
1515
/**

core/kotlinx-coroutines-core/src/channels/Actor.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ interface ActorJob<in E> : SendChannel<E> {
6565
* * when `capacity` is positive, but less than [UNLIMITED] -- uses [ArrayChannel] with a buffer of the specified `capacity`;
6666
* * otherwise -- throws [IllegalArgumentException].
6767
*
68-
* See [newCoroutineContext] for a description of debugging facilities that are available for newly created coroutine.
68+
* See [newCoroutineContext][CoroutineScope.newCoroutineContext] for a description of debugging facilities that are available for newly created coroutine.
6969
*
7070
* ### Using actors
7171
*

0 commit comments

Comments
 (0)