Structured concurrency for guava, jdk8 and promise modules, proper reference to newCoroutineContext
diff --git a/binary-compatibility-validator/reference-public-api/kotlinx-coroutines-core.txt b/binary-compatibility-validator/reference-public-api/kotlinx-coroutines-core.txt
index 0080665..0a7848f 100644
--- a/binary-compatibility-validator/reference-public-api/kotlinx-coroutines-core.txt
+++ b/binary-compatibility-validator/reference-public-api/kotlinx-coroutines-core.txt
@@ -144,6 +144,7 @@
public static final fun getIO ()Lkotlinx/coroutines/experimental/CoroutineDispatcher;
public static final fun newCoroutineContext (Lkotlin/coroutines/experimental/CoroutineContext;)Lkotlin/coroutines/experimental/CoroutineContext;
public static final fun newCoroutineContext (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/Job;)Lkotlin/coroutines/experimental/CoroutineContext;
+ public static final fun newCoroutineContext (Lkotlinx/coroutines/experimental/CoroutineScope;Lkotlin/coroutines/experimental/CoroutineContext;)Lkotlin/coroutines/experimental/CoroutineContext;
public static synthetic fun newCoroutineContext$default (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/Job;ILjava/lang/Object;)Lkotlin/coroutines/experimental/CoroutineContext;
}
diff --git a/binary-compatibility-validator/reference-public-api/kotlinx-coroutines-guava.txt b/binary-compatibility-validator/reference-public-api/kotlinx-coroutines-guava.txt
index 02056de..efb5ce2 100644
--- a/binary-compatibility-validator/reference-public-api/kotlinx-coroutines-guava.txt
+++ b/binary-compatibility-validator/reference-public-api/kotlinx-coroutines-guava.txt
@@ -1,11 +1,15 @@
public final class kotlinx/coroutines/experimental/guava/ListenableFutureKt {
public static final fun asListenableFuture (Lkotlinx/coroutines/experimental/Deferred;)Lcom/google/common/util/concurrent/ListenableFuture;
public static final fun await (Lcom/google/common/util/concurrent/ListenableFuture;Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object;
+ 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;
public static final synthetic fun future (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlin/jvm/functions/Function2;)Lcom/google/common/util/concurrent/ListenableFuture;
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;
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;
+ 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;
+ 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;
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;
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;
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;
+ 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;
}
diff --git a/binary-compatibility-validator/reference-public-api/kotlinx-coroutines-jdk8.txt b/binary-compatibility-validator/reference-public-api/kotlinx-coroutines-jdk8.txt
index c2c5c4b..94fb357 100644
--- a/binary-compatibility-validator/reference-public-api/kotlinx-coroutines-jdk8.txt
+++ b/binary-compatibility-validator/reference-public-api/kotlinx-coroutines-jdk8.txt
@@ -11,13 +11,17 @@
public static final synthetic fun await (Ljava/util/concurrent/CompletableFuture;Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object;
public static final fun await (Ljava/util/concurrent/CompletionStage;Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object;
public static final synthetic fun future (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlin/jvm/functions/Function1;)Ljava/util/concurrent/CompletableFuture;
+ 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;
public static final synthetic fun future (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlin/jvm/functions/Function2;)Ljava/util/concurrent/CompletableFuture;
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;
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;
+ 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;
public static synthetic fun future$default (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/util/concurrent/CompletableFuture;
+ 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;
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;
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;
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;
+ 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;
public static final fun toCompletableFuture (Lkotlinx/coroutines/experimental/Deferred;)Ljava/util/concurrent/CompletableFuture;
}
diff --git a/common/kotlinx-coroutines-core-common/src/CoroutineContext.common.kt b/common/kotlinx-coroutines-core-common/src/CoroutineContext.common.kt
index f952c8d..4cac79c 100644
--- a/common/kotlinx-coroutines-core-common/src/CoroutineContext.common.kt
+++ b/common/kotlinx-coroutines-core-common/src/CoroutineContext.common.kt
@@ -6,7 +6,7 @@
import kotlin.coroutines.experimental.*
-public expect fun newCoroutineContext(context: CoroutineContext, parent: Job? = null): CoroutineContext
+public expect fun CoroutineScope.newCoroutineContext(context: CoroutineContext): CoroutineContext
@Suppress("PropertyName")
public expect val DefaultDispatcher: CoroutineDispatcher
diff --git a/common/kotlinx-coroutines-core-common/src/Deferred.kt b/common/kotlinx-coroutines-core-common/src/Deferred.kt
index c7b8fe1..3266540 100644
--- a/common/kotlinx-coroutines-core-common/src/Deferred.kt
+++ b/common/kotlinx-coroutines-core-common/src/Deferred.kt
@@ -125,9 +125,7 @@
/**
* Creates new coroutine and returns its future result as an implementation of [Deferred].
- *
* The running coroutine is cancelled when the resulting deferred is [cancelled][Job.cancel].
- * Parent of the created coroutine is inherited from the provided [CoroutineScope].
*
* 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 [DefaultDispatcher] is used.
diff --git a/common/kotlinx-coroutines-core-common/src/channels/Broadcast.kt b/common/kotlinx-coroutines-core-common/src/channels/Broadcast.kt
index 0f6b418..009cccc 100644
--- a/common/kotlinx-coroutines-core-common/src/channels/Broadcast.kt
+++ b/common/kotlinx-coroutines-core-common/src/channels/Broadcast.kt
@@ -7,7 +7,6 @@
import kotlinx.coroutines.experimental.*
import kotlinx.coroutines.experimental.channels.Channel.Factory.CONFLATED
import kotlinx.coroutines.experimental.channels.Channel.Factory.UNLIMITED
-import kotlinx.coroutines.experimental.internal.*
import kotlinx.coroutines.experimental.intrinsics.*
import kotlin.coroutines.experimental.*
@@ -21,7 +20,7 @@
capacity: Int = 1,
start: CoroutineStart = CoroutineStart.LAZY
) : BroadcastChannel<E> =
- broadcast(Unconfined, capacity = capacity, start = start, onCompletion = consumes()) {
+ GlobalScope.broadcast(Unconfined, capacity = capacity, start = start, onCompletion = consumes()) {
for (e in this@broadcast) {
send(e)
}
@@ -29,9 +28,13 @@
/**
* Launches new coroutine to produce a stream of values by sending them to a broadcast channel.
- * Deprecated, use [CoroutineScope.broadcast] instead.
+ * @suppress **Deprecated**: use [CoroutineScope.broadcast] instead.
*/
-@Deprecated(message = "Standalone coroutine builders are deprecated, use extensions on CoroutineScope instead. This API will be hidden in the next release")
+@Deprecated(
+ message = "Standalone coroutine builders are deprecated, use extensions on CoroutineScope instead",
+ replaceWith = ReplaceWith("GlobalScope.broadcast(context + parent, capacity, start, onCompletion, block)",
+ imports = ["kotlinx.coroutines.experimental.GlobalScope", "kotlinx.coroutines.experimental.channels.broadcast"])
+)
public fun <E> broadcast(
context: CoroutineContext = DefaultDispatcher,
capacity: Int = 1,
@@ -39,16 +42,8 @@
parent: Job? = null,
onCompletion: CompletionHandler? = null,
block: suspend ProducerScope<E>.() -> Unit
-): BroadcastChannel<E> {
- val channel = BroadcastChannel<E>(capacity)
- val newContext = newCoroutineContext(context, parent)
- val coroutine = if (start.isLazy)
- LazyBroadcastCoroutine(newContext, channel, block) else
- BroadcastCoroutine(newContext, channel, active = true)
- if (onCompletion != null) coroutine.invokeOnCompletion(handler = onCompletion)
- coroutine.start(start, coroutine, block)
- return coroutine
-}
+): BroadcastChannel<E> =
+ GlobalScope.broadcast(context + (parent ?: DefaultDispatcher), capacity, start, onCompletion, block)
/**
* Launches new coroutine to produce a stream of values by sending them to a broadcast channel
diff --git a/common/kotlinx-coroutines-core-common/src/internal/Scopes.kt b/common/kotlinx-coroutines-core-common/src/internal/Scopes.kt
index ee51615..e2e7475 100644
--- a/common/kotlinx-coroutines-core-common/src/internal/Scopes.kt
+++ b/common/kotlinx-coroutines-core-common/src/internal/Scopes.kt
@@ -25,6 +25,3 @@
internal class ContextScope(context: CoroutineContext) : CoroutineScope {
override val coroutineContext: CoroutineContext = context
}
-
-internal fun CoroutineScope.newCoroutineContext(context: CoroutineContext): CoroutineContext =
- newCoroutineContext(coroutineContext + context, parent = null)
diff --git a/core/kotlinx-coroutines-core/src/Builders.kt b/core/kotlinx-coroutines-core/src/Builders.kt
index 8002100..43521c2 100644
--- a/core/kotlinx-coroutines-core/src/Builders.kt
+++ b/core/kotlinx-coroutines-core/src/Builders.kt
@@ -27,7 +27,7 @@
* If this blocked thread is interrupted (see [Thread.interrupt]), then the coroutine job is cancelled and
* this `runBlocking` invocation throws [InterruptedException].
*
- * See [newCoroutineContext] for a description of debugging facilities that are available for newly created coroutine.
+ * See [newCoroutineContext][CoroutineScope.newCoroutineContext] for a description of debugging facilities that are available for newly created coroutine.
*
* @param context context of the coroutine. The default value is an implementation of [EventLoop].
* @param block the coroutine code.
@@ -38,7 +38,7 @@
val contextInterceptor = context[ContinuationInterceptor]
val privateEventLoop = contextInterceptor == null // create private event loop if no dispatcher is specified
val eventLoop = if (privateEventLoop) BlockingEventLoop(currentThread) else contextInterceptor as? EventLoop
- val newContext = newCoroutineContext(
+ val newContext = GlobalScope.newCoroutineContext(
if (privateEventLoop) context + (eventLoop as ContinuationInterceptor) else context
)
val coroutine = BlockingCoroutine<T>(newContext, currentThread, eventLoop, privateEventLoop)
diff --git a/core/kotlinx-coroutines-core/src/CoroutineContext.kt b/core/kotlinx-coroutines-core/src/CoroutineContext.kt
index b46e856..853ccfd 100644
--- a/core/kotlinx-coroutines-core/src/CoroutineContext.kt
+++ b/core/kotlinx-coroutines-core/src/CoroutineContext.kt
@@ -10,22 +10,22 @@
import kotlin.coroutines.experimental.*
/**
- * Name of the property that controls coroutine debugging. See [newCoroutineContext].
+ * Name of the property that controls coroutine debugging. See [newCoroutineContext][CoroutineScope.newCoroutineContext].
*/
public const val DEBUG_PROPERTY_NAME = "kotlinx.coroutines.debug"
/**
- * Automatic debug configuration value for [DEBUG_PROPERTY_NAME]. See [newCoroutineContext].
+ * Automatic debug configuration value for [DEBUG_PROPERTY_NAME]. See [newCoroutineContext][CoroutineScope.newCoroutineContext].
*/
public const val DEBUG_PROPERTY_VALUE_AUTO = "auto"
/**
- * Debug turned on value for [DEBUG_PROPERTY_NAME]. See [newCoroutineContext].
+ * Debug turned on value for [DEBUG_PROPERTY_NAME]. See [newCoroutineContext][CoroutineScope.newCoroutineContext].
*/
public const val DEBUG_PROPERTY_VALUE_ON = "on"
/**
- * Debug turned on value for [DEBUG_PROPERTY_NAME]. See [newCoroutineContext].
+ * Debug turned on value for [DEBUG_PROPERTY_NAME]. See [newCoroutineContext][CoroutineScope.newCoroutineContext].
*/
public const val DEBUG_PROPERTY_VALUE_OFF = "off"
@@ -106,14 +106,24 @@
* Coroutine name can be explicitly assigned using [CoroutineName] context element.
* The string "coroutine" is used as a default name.
*/
+public actual fun CoroutineScope.newCoroutineContext(context: CoroutineContext): CoroutineContext {
+ val combined = coroutineContext + context
+ val debug = if (DEBUG) combined + CoroutineId(COROUTINE_ID.incrementAndGet()) else combined
+ return if (combined !== DefaultDispatcher && combined[ContinuationInterceptor] == null)
+ debug + DefaultDispatcher else debug
+}
+
+/**
+ * @suppress **Deprecated**: Use extension on CoroutineScope.
+ */
@JvmOverloads // for binary compatibility with newCoroutineContext(context: CoroutineContext) version
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
-public actual fun newCoroutineContext(context: CoroutineContext, parent: Job? = null): CoroutineContext {
- val debug = if (DEBUG) context + CoroutineId(COROUTINE_ID.incrementAndGet()) else context
- val wp = if (parent == null) debug else debug + parent
- return if (context !== DefaultDispatcher && context[ContinuationInterceptor] == null)
- wp + DefaultDispatcher else wp
-}
+@Deprecated(
+ message = "Use extension on CoroutineScope",
+ replaceWith = ReplaceWith("GlobalScope.newCoroutineContext(context + parent)")
+)
+public fun newCoroutineContext(context: CoroutineContext, parent: Job? = null): CoroutineContext =
+ GlobalScope.newCoroutineContext(context + (parent ?: EmptyCoroutineContext))
/**
* Executes a block using a given coroutine context.
diff --git a/core/kotlinx-coroutines-core/src/CoroutineName.kt b/core/kotlinx-coroutines-core/src/CoroutineName.kt
index 0430d65..8f8131e 100644
--- a/core/kotlinx-coroutines-core/src/CoroutineName.kt
+++ b/core/kotlinx-coroutines-core/src/CoroutineName.kt
@@ -9,7 +9,7 @@
/**
* User-specified name of coroutine. This name is used in debugging mode.
- * See [newCoroutineContext] for the description of coroutine debugging facilities.
+ * See [newCoroutineContext][CoroutineScope.newCoroutineContext] for the description of coroutine debugging facilities.
*/
public data class CoroutineName(
/**
diff --git a/core/kotlinx-coroutines-core/src/channels/Actor.kt b/core/kotlinx-coroutines-core/src/channels/Actor.kt
index cf01902..115ae03 100644
--- a/core/kotlinx-coroutines-core/src/channels/Actor.kt
+++ b/core/kotlinx-coroutines-core/src/channels/Actor.kt
@@ -65,7 +65,7 @@
* * when `capacity` is positive, but less than [UNLIMITED] -- uses [ArrayChannel] with a buffer of the specified `capacity`;
* * otherwise -- throws [IllegalArgumentException].
*
- * See [newCoroutineContext] for a description of debugging facilities that are available for newly created coroutine.
+ * See [newCoroutineContext][CoroutineScope.newCoroutineContext] for a description of debugging facilities that are available for newly created coroutine.
*
* ### Using actors
*
diff --git a/integration/kotlinx-coroutines-guava/src/ListenableFuture.kt b/integration/kotlinx-coroutines-guava/src/ListenableFuture.kt
index 984014a..29eb8ca 100644
--- a/integration/kotlinx-coroutines-guava/src/ListenableFuture.kt
+++ b/integration/kotlinx-coroutines-guava/src/ListenableFuture.kt
@@ -11,17 +11,12 @@
/**
* Starts new coroutine and returns its results an an implementation of [ListenableFuture].
- * This coroutine builder uses [DefaultDispatcher] context by default.
- *
* The running coroutine is cancelled when the resulting future is cancelled or otherwise completed.
*
- * The [context] for the new coroutine can be explicitly specified.
- * See [CoroutineDispatcher] for the standard context implementations that are provided by `kotlinx.coroutines`.
- * The [coroutineContext] of the parent coroutine may be used,
- * in which case the [Job] of the resulting coroutine is a child of the job of the parent coroutine.
- * The parent job may be also explicitly specified using [parent] parameter.
- *
+ * 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 [DefaultDispatcher] is used.
+ * The parent job is inherited from a [CoroutineScope] as well, but it can also be overridden
+ * with corresponding [coroutineContext] element.
*
* By default, the coroutine is immediately scheduled for execution.
* Other options can be specified via `start` parameter. See [CoroutineStart] for details.
@@ -29,7 +24,7 @@
* (since `ListenableFuture` framework does not provide the corresponding capability) and
* produces [IllegalArgumentException].
*
- * See [newCoroutineContext] for a description of debugging facilities that are available for newly created coroutine.
+ * See [newCoroutineContext][CoroutineScope.newCoroutineContext] for a description of debugging facilities that are available for newly created coroutine.
*
* @param context context of the coroutine. The default value is [DefaultDispatcher].
* @param start coroutine start option. The default value is [CoroutineStart.DEFAULT].
@@ -37,15 +32,14 @@
* @param onCompletion optional completion handler for the coroutine (see [Job.invokeOnCompletion]).
* @param block the coroutine code.
*/
-public fun <T> future(
+public fun <T> CoroutineScope.future(
context: CoroutineContext = DefaultDispatcher,
start: CoroutineStart = CoroutineStart.DEFAULT,
- parent: Job? = null,
onCompletion: CompletionHandler? = null,
block: suspend CoroutineScope.() -> T
): ListenableFuture<T> {
require(!start.isLazy) { "$start start is not supported" }
- val newContext = newCoroutineContext(context, parent)
+ val newContext = newCoroutineContext(context)
val job = Job(newContext[Job])
val future = ListenableFutureCoroutine<T>(newContext + job)
job.cancelFutureOnCompletion(future)
@@ -54,6 +48,41 @@
return future
}
+/**
+ * Starts new coroutine and returns its results an an implementation of [ListenableFuture].
+ * @suppress **Deprecated**. Use [CoroutineScope.future] instead.
+ */
+@Deprecated(
+ message = "Standalone coroutine builders are deprecated, use extensions on CoroutineScope instead",
+ replaceWith = ReplaceWith("GlobalScope.future(context, start, onCompletion, block)",
+ imports = ["kotlinx.coroutines.experimental.GlobalScope", "kotlinx.coroutines.experimental.future.future"])
+)
+public fun <T> future(
+ context: CoroutineContext = DefaultDispatcher,
+ start: CoroutineStart = CoroutineStart.DEFAULT,
+ onCompletion: CompletionHandler? = null,
+ block: suspend CoroutineScope.() -> T
+): ListenableFuture<T> =
+ GlobalScope.future(context, start, onCompletion, block)
+
+/**
+ * Starts new coroutine and returns its results an an implementation of [ListenableFuture].
+ * @suppress **Deprecated**. Use [CoroutineScope.future] instead.
+ */
+@Deprecated(
+ message = "Standalone coroutine builders are deprecated, use extensions on CoroutineScope instead",
+ replaceWith = ReplaceWith("GlobalScope.future(context + parent, start, onCompletion, block)",
+ imports = ["kotlinx.coroutines.experimental.GlobalScope", "kotlinx.coroutines.experimental.future.future"])
+)
+public fun <T> future(
+ context: CoroutineContext = DefaultDispatcher,
+ start: CoroutineStart = CoroutineStart.DEFAULT,
+ parent: Job? = null,
+ onCompletion: CompletionHandler? = null,
+ block: suspend CoroutineScope.() -> T
+): ListenableFuture<T> =
+ GlobalScope.future(context + (parent ?: EmptyCoroutineContext), start, onCompletion, block)
+
/** @suppress **Deprecated**: Binary compatibility */
@Deprecated(message = "Binary compatibility", level = DeprecationLevel.HIDDEN)
public fun <T> future(
@@ -61,7 +90,8 @@
start: CoroutineStart = CoroutineStart.DEFAULT,
parent: Job? = null,
block: suspend CoroutineScope.() -> T
-): ListenableFuture<T> = future(context, start, parent, block = block)
+): ListenableFuture<T> =
+ GlobalScope.future(context + (parent ?: EmptyCoroutineContext), start, block = block)
/** @suppress **Deprecated**: Binary compatibility */
@Deprecated(message = "Binary compatibility", level = DeprecationLevel.HIDDEN)
@@ -70,7 +100,7 @@
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T
): ListenableFuture<T> =
- future(context, start, block = block)
+ GlobalScope.future(context, start, block = block)
private class ListenableFutureCoroutine<T>(
override val context: CoroutineContext
@@ -108,7 +138,7 @@
*
* This suspending function is cancellable.
* If the [Job] of the current coroutine is cancelled or completed while this suspending function is waiting, this function
- * stops waiting for the future and immediately resumes with [CancellationException].
+ * stops waiting for the future and immediately resumes with [CancellationException][kotlinx.coroutines.experimental.CancellationException].
*
* Note, that `ListenableFuture` does not support removal of installed listeners, so on cancellation of this wait
* a few small objects will remain in the `ListenableFuture` list of listeners until the future completes. However, the
diff --git a/integration/kotlinx-coroutines-guava/test/ListenableFutureTest.kt b/integration/kotlinx-coroutines-guava/test/ListenableFutureTest.kt
index c1dc20c..25f19f3 100644
--- a/integration/kotlinx-coroutines-guava/test/ListenableFutureTest.kt
+++ b/integration/kotlinx-coroutines-guava/test/ListenableFutureTest.kt
@@ -22,7 +22,7 @@
@Test
fun testSimpleAwait() {
val service = MoreExecutors.listeningDecorator(ForkJoinPool.commonPool())
- val future = future {
+ val future = GlobalScope.future {
service.submit(Callable<String> {
"O"
}).await() + "K"
@@ -33,7 +33,7 @@
@Test
fun testAwaitWithContext() = runTest {
val future = SettableFuture.create<Int>()
- val deferred = async(coroutineContext) {
+ val deferred = async {
withContext(DefaultDispatcher) {
future.await()
}
@@ -46,7 +46,7 @@
@Test
fun testAwaitWithContextCancellation() = runTest(expected = {it is IOException}) {
val future = SettableFuture.create<Int>()
- val deferred = async(coroutineContext) {
+ val deferred = async {
withContext(DefaultDispatcher) {
future.await()
}
@@ -60,7 +60,7 @@
fun testCompletedFuture() {
val toAwait = SettableFuture.create<String>()
toAwait.set("O")
- val future = future {
+ val future = GlobalScope.future {
toAwait.await() + "K"
}
assertThat(future.get(), IsEqual("OK"))
@@ -69,7 +69,7 @@
@Test
fun testWaitForFuture() {
val toAwait = SettableFuture.create<String>()
- val future = future {
+ val future = GlobalScope.future {
toAwait.await() + "K"
}
assertFalse(future.isDone)
@@ -81,7 +81,7 @@
fun testCompletedFutureExceptionally() {
val toAwait = SettableFuture.create<String>()
toAwait.setException(IllegalArgumentException("O"))
- val future = future<String> {
+ val future = GlobalScope.future {
try {
toAwait.await()
} catch (e: RuntimeException) {
@@ -95,7 +95,7 @@
@Test
fun testWaitForFutureWithException() {
val toAwait = SettableFuture.create<String>()
- val future = future<String> {
+ val future = GlobalScope.future {
try {
toAwait.await()
} catch (e: RuntimeException) {
@@ -111,7 +111,7 @@
@Test
fun testExceptionInsideCoroutine() {
val service = MoreExecutors.listeningDecorator(ForkJoinPool.commonPool())
- val future = future {
+ val future = GlobalScope.future {
if (service.submit(Callable<Boolean> { true }).await()) {
throw IllegalStateException("OK")
}
diff --git a/integration/kotlinx-coroutines-jdk8/src/future/Future.kt b/integration/kotlinx-coroutines-jdk8/src/future/Future.kt
index 54233e4..0250d4f 100644
--- a/integration/kotlinx-coroutines-jdk8/src/future/Future.kt
+++ b/integration/kotlinx-coroutines-jdk8/src/future/Future.kt
@@ -11,18 +11,13 @@
/**
* Starts new coroutine and returns its result as an implementation of [CompletableFuture].
- * This coroutine builder uses [DefaultDispatcher] context by default and is conceptually similar to [CompletableFuture.supplyAsync].
*
* The running coroutine is cancelled when the resulting future is cancelled or otherwise completed.
*
- * The [context] for the new coroutine can be explicitly specified.
- * See [CoroutineDispatcher] for the standard context implementations that are provided by `kotlinx.coroutines`.
- * The [coroutineContext](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.coroutines.experimental/coroutine-context.html)
- * of the parent coroutine may be used,
- * in which case the [Job] of the resulting coroutine is a child of the job of the parent coroutine.
- * The parent job may be also explicitly specified using [parent] parameter.
- *
+ * 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 [DefaultDispatcher] is used.
+ * The parent job is inherited from a [CoroutineScope] as well, but it can also be overridden
+ * with corresponding [coroutineContext] element.
*
* By default, the coroutine is immediately scheduled for execution.
* Other options can be specified via `start` parameter. See [CoroutineStart] for details.
@@ -30,23 +25,21 @@
* (since `CompletableFuture` framework does not provide the corresponding capability) and
* produces [IllegalArgumentException].
*
- * See [newCoroutineContext] for a description of debugging facilities that are available for newly created coroutine.
+ * See [newCoroutineContext][CoroutineScope.newCoroutineContext] for a description of debugging facilities that are available for newly created coroutine.
*
* @param context context of the coroutine. The default value is [DefaultDispatcher].
* @param start coroutine start option. The default value is [CoroutineStart.DEFAULT].
- * @param parent explicitly specifies the parent job, overrides job from the [context] (if any).
* @param onCompletion optional completion handler for the coroutine (see [Job.invokeOnCompletion]).
* @param block the coroutine code.
*/
-public fun <T> future(
+public fun <T> CoroutineScope.future(
context: CoroutineContext = DefaultDispatcher,
start: CoroutineStart = CoroutineStart.DEFAULT,
- parent: Job? = null,
onCompletion: CompletionHandler? = null,
block: suspend CoroutineScope.() -> T
): CompletableFuture<T> {
require(!start.isLazy) { "$start start is not supported" }
- val newContext = newCoroutineContext(context, parent)
+ val newContext = this.newCoroutineContext(context)
val job = Job(newContext[Job])
val future = CompletableFutureCoroutine<T>(newContext + job)
job.cancelFutureOnCompletion(future)
@@ -56,6 +49,41 @@
return future
}
+/**
+ * Starts new coroutine and returns its result as an implementation of [CompletableFuture].
+ * @suppress **Deprecated**. Use [CoroutineScope.future] instead.
+ */
+@Deprecated(
+ message = "Standalone coroutine builders are deprecated, use extensions on CoroutineScope instead",
+ replaceWith = ReplaceWith("GlobalScope.future(context, start, onCompletion, block)",
+ imports = ["kotlinx.coroutines.experimental.GlobalScope", "kotlinx.coroutines.experimental.future.future"])
+)
+public fun <T> future(
+ context: CoroutineContext = DefaultDispatcher,
+ start: CoroutineStart = CoroutineStart.DEFAULT,
+ onCompletion: CompletionHandler? = null,
+ block: suspend CoroutineScope.() -> T
+): CompletableFuture<T> =
+ GlobalScope.future(context, start, onCompletion, block)
+
+/**
+ * Starts new coroutine and returns its result as an implementation of [CompletableFuture].
+ * @suppress **Deprecated**. Use [CoroutineScope.future] instead.
+ */
+@Deprecated(
+ message = "Standalone coroutine builders are deprecated, use extensions on CoroutineScope instead",
+ replaceWith = ReplaceWith("GlobalScope.future(context + parent, start, onCompletion, block)",
+ imports = ["kotlinx.coroutines.experimental.GlobalScope", "kotlinx.coroutines.experimental.future.future"])
+)
+public fun <T> future(
+ context: CoroutineContext = DefaultDispatcher,
+ start: CoroutineStart = CoroutineStart.DEFAULT,
+ parent: Job? = null,
+ onCompletion: CompletionHandler? = null,
+ block: suspend CoroutineScope.() -> T
+): CompletableFuture<T> =
+ GlobalScope.future(context + (parent ?: EmptyCoroutineContext), start, onCompletion, block)
+
/** @suppress **Deprecated**: Binary compatibility */
@Deprecated(message = "Binary compatibility", level = DeprecationLevel.HIDDEN)
public fun <T> future(
@@ -72,7 +100,7 @@
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T
): CompletableFuture<T> =
- future(context, start, block = block)
+ GlobalScope.future(context, start, block = block)
private class CompletableFutureCoroutine<T>(
override val context: CoroutineContext
@@ -205,4 +233,5 @@
public fun <T> future(
context: CoroutineContext = DefaultDispatcher,
block: suspend () -> T
-): CompletableFuture<T> = future(context = context) { block() }
+): CompletableFuture<T> =
+ GlobalScope.future(context = context, block = { block() })
diff --git a/integration/kotlinx-coroutines-jdk8/test/examples/CancelFuture-example.kt b/integration/kotlinx-coroutines-jdk8/test/examples/CancelFuture-example.kt
index b5c01e6..c8617f3 100644
--- a/integration/kotlinx-coroutines-jdk8/test/examples/CancelFuture-example.kt
+++ b/integration/kotlinx-coroutines-jdk8/test/examples/CancelFuture-example.kt
@@ -4,12 +4,12 @@
package kotlinx.coroutines.experimental.examples
-import kotlinx.coroutines.experimental.delay
-import kotlinx.coroutines.experimental.future.future
+import kotlinx.coroutines.experimental.*
+import kotlinx.coroutines.experimental.future.*
fun main(args: Array<String>) {
- val f = future {
+ val f = GlobalScope.future {
try {
log("Started f")
delay(500)
diff --git a/integration/kotlinx-coroutines-jdk8/test/examples/ExplicitJob-example.kt b/integration/kotlinx-coroutines-jdk8/test/examples/ExplicitJob-example.kt
index 4112665..789b136 100644
--- a/integration/kotlinx-coroutines-jdk8/test/examples/ExplicitJob-example.kt
+++ b/integration/kotlinx-coroutines-jdk8/test/examples/ExplicitJob-example.kt
@@ -4,20 +4,19 @@
package kotlinx.coroutines.experimental.examples
-import kotlinx.coroutines.experimental.Job
-import kotlinx.coroutines.experimental.delay
-import kotlinx.coroutines.experimental.future.future
+import kotlinx.coroutines.experimental.*
+import kotlinx.coroutines.experimental.future.*
import java.util.concurrent.CancellationException
fun main(args: Array<String>) {
val job = Job()
log("Starting futures f && g")
- val f = future(job) {
+ val f = GlobalScope.future(job) {
log("Started f")
delay(500)
log("f should not execute this line")
}
- val g = future(job) {
+ val g = GlobalScope.future(job) {
log("Started g")
try {
delay(500)
diff --git a/integration/kotlinx-coroutines-jdk8/test/examples/simple-example-2.kt b/integration/kotlinx-coroutines-jdk8/test/examples/simple-example-2.kt
index e2608bb..9de9798 100644
--- a/integration/kotlinx-coroutines-jdk8/test/examples/simple-example-2.kt
+++ b/integration/kotlinx-coroutines-jdk8/test/examples/simple-example-2.kt
@@ -4,13 +4,12 @@
package kotlinx.coroutines.experimental.examples
-import kotlinx.coroutines.experimental.delay
-import kotlinx.coroutines.experimental.future.future
-import java.util.concurrent.CompletableFuture
-import java.util.concurrent.TimeUnit
+import kotlinx.coroutines.experimental.*
+import kotlinx.coroutines.experimental.future.*
+import java.util.concurrent.*
// this function returns a CompletableFuture using Kotlin coroutines
-fun supplyTheAnswerAsync(): CompletableFuture<Int> = future {
+fun supplyTheAnswerAsync(): CompletableFuture<Int> = GlobalScope.future {
println("We might be doing some asynchronous IO here or something else...")
delay(1, TimeUnit.SECONDS) // just do a non-blocking delay
42 // The answer!
diff --git a/integration/kotlinx-coroutines-jdk8/test/examples/simple-example-3.kt b/integration/kotlinx-coroutines-jdk8/test/examples/simple-example-3.kt
index ee09a87..cd683aa 100644
--- a/integration/kotlinx-coroutines-jdk8/test/examples/simple-example-3.kt
+++ b/integration/kotlinx-coroutines-jdk8/test/examples/simple-example-3.kt
@@ -4,13 +4,13 @@
package kotlinx.coroutines.experimental.examples
-import kotlinx.coroutines.experimental.future.await
-import kotlinx.coroutines.experimental.future.future
-import java.util.concurrent.CompletableFuture
+import kotlinx.coroutines.experimental.*
+import kotlinx.coroutines.experimental.future.*
+import java.util.concurrent.*
fun main(args: Array<String>) {
// this example shows how easy it is to perform multiple async operations with coroutines
- val future = future {
+ val future = GlobalScope.future {
(1..5).map { // loops are no problem at all
startLongAsyncOperation(it).await() // suspend while the long method is running
}.joinToString("\n")
diff --git a/integration/kotlinx-coroutines-jdk8/test/examples/withTimeout-example.kt b/integration/kotlinx-coroutines-jdk8/test/examples/withTimeout-example.kt
index 0d79637..332e34c 100644
--- a/integration/kotlinx-coroutines-jdk8/test/examples/withTimeout-example.kt
+++ b/integration/kotlinx-coroutines-jdk8/test/examples/withTimeout-example.kt
@@ -8,11 +8,11 @@
import kotlinx.coroutines.experimental.future.*
fun main(args: Array<String>) {
- fun slow(s: String) = future {
+ fun slow(s: String) = GlobalScope.future {
delay(500L)
s
}
- val f = future<String> {
+ val f = GlobalScope.future {
log("Started f")
val a = slow("A").await()
log("a = $a")
diff --git a/integration/kotlinx-coroutines-jdk8/test/future/FutureTest.kt b/integration/kotlinx-coroutines-jdk8/test/future/FutureTest.kt
index dac314c..1c403d1 100644
--- a/integration/kotlinx-coroutines-jdk8/test/future/FutureTest.kt
+++ b/integration/kotlinx-coroutines-jdk8/test/future/FutureTest.kt
@@ -24,7 +24,7 @@
@Test
fun testSimpleAwait() {
- val future = future {
+ val future = GlobalScope.future {
CompletableFuture.supplyAsync {
"O"
}.await() + "K"
@@ -36,7 +36,7 @@
fun testCompletedFuture() {
val toAwait = CompletableFuture<String>()
toAwait.complete("O")
- val future = future {
+ val future = GlobalScope.future {
toAwait.await() + "K"
}
assertThat(future.get(), IsEqual("OK"))
@@ -47,7 +47,7 @@
val completable = CompletableFuture<String>()
completable.complete("O")
val toAwait: CompletionStage<String> = completable
- val future = future {
+ val future = GlobalScope.future {
toAwait.await() + "K"
}
assertThat(future.get(), IsEqual("OK"))
@@ -56,7 +56,7 @@
@Test
fun testWaitForFuture() {
val toAwait = CompletableFuture<String>()
- val future = future {
+ val future = GlobalScope.future {
toAwait.await() + "K"
}
assertFalse(future.isDone)
@@ -68,7 +68,7 @@
fun testWaitForCompletionStage() {
val completable = CompletableFuture<String>()
val toAwait: CompletionStage<String> = completable
- val future = future {
+ val future = GlobalScope.future {
toAwait.await() + "K"
}
assertFalse(future.isDone)
@@ -80,7 +80,7 @@
fun testCompletedFutureExceptionally() {
val toAwait = CompletableFuture<String>()
toAwait.completeExceptionally(TestException("O"))
- val future = future {
+ val future = GlobalScope.future {
try {
toAwait.await()
} catch (e: TestException) {
@@ -96,7 +96,7 @@
val completable = CompletableFuture<String>()
val toAwait: CompletionStage<String> = completable
completable.completeExceptionally(TestException("O"))
- val future = future {
+ val future = GlobalScope.future {
try {
toAwait.await()
} catch (e: TestException) {
@@ -132,7 +132,7 @@
fun testWaitForCompletionStageWithException() {
val completable = CompletableFuture<String>()
val toAwait: CompletionStage<String> = completable
- val future = future {
+ val future = GlobalScope.future {
try {
toAwait.await()
} catch (e: TestException) {
@@ -146,7 +146,7 @@
@Test
fun testExceptionInsideCoroutine() {
- val future = future {
+ val future = GlobalScope.future {
if (CompletableFuture.supplyAsync { true }.await()) {
throw IllegalStateException("OK")
}
@@ -226,7 +226,7 @@
@Test
fun testContinuationWrapped() {
val depth = AtomicInteger()
- val future = future(wrapContinuation {
+ val future = GlobalScope.future(wrapContinuation {
depth.andIncrement
it()
depth.andDecrement
diff --git a/integration/kotlinx-coroutines-quasar/src/Quasar.kt b/integration/kotlinx-coroutines-quasar/src/Quasar.kt
index 7dd693e..182d799 100644
--- a/integration/kotlinx-coroutines-quasar/src/Quasar.kt
+++ b/integration/kotlinx-coroutines-quasar/src/Quasar.kt
@@ -44,7 +44,7 @@
private val block: suspend () -> T
) : FiberAsync<T, Throwable>(), Continuation<T> {
override val context: CoroutineContext =
- newCoroutineContext(Fiber.currentFiber().scheduler.executor.asCoroutineDispatcher())
+ GlobalScope.newCoroutineContext(Fiber.currentFiber().scheduler.executor.asCoroutineDispatcher())
override fun resume(value: T) { asyncCompleted(value) }
override fun resumeWithException(exception: Throwable) { asyncFailed(exception) }
diff --git a/js/kotlinx-coroutines-core-js/src/CoroutineContext.kt b/js/kotlinx-coroutines-core-js/src/CoroutineContext.kt
index 2b6bf4b..bc065c0 100644
--- a/js/kotlinx-coroutines-core-js/src/CoroutineContext.kt
+++ b/js/kotlinx-coroutines-core-js/src/CoroutineContext.kt
@@ -27,15 +27,10 @@
internal actual val DefaultDelay: Delay = DefaultDispatcher as Delay
-/**
- * Creates context for the new coroutine. It installs [DefaultDispatcher] when no other dispatcher nor
- * [ContinuationInterceptor] is specified, and adds optional support for debugging facilities (when turned on).
- */
-@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
-public actual fun newCoroutineContext(context: CoroutineContext, parent: Job? = null): CoroutineContext {
- val wp = if (parent == null) context else context + parent
- return if (context !== DefaultDispatcher && context[ContinuationInterceptor] == null)
- wp + DefaultDispatcher else wp
+public actual fun CoroutineScope.newCoroutineContext(context: CoroutineContext): CoroutineContext {
+ val combined = coroutineContext + context
+ return if (combined !== DefaultDispatcher && combined[ContinuationInterceptor] == null)
+ combined + DefaultDispatcher else combined
}
// No debugging facilities on JS
diff --git a/js/kotlinx-coroutines-core-js/src/Promise.kt b/js/kotlinx-coroutines-core-js/src/Promise.kt
index 11e84f4..4452a2a 100644
--- a/js/kotlinx-coroutines-core-js/src/Promise.kt
+++ b/js/kotlinx-coroutines-core-js/src/Promise.kt
@@ -10,24 +10,53 @@
/**
* Starts new coroutine and returns its result as an implementation of [Promise].
*
- * The [context] for the new coroutine can be explicitly specified.
- * See [CoroutineDispatcher] for the standard context implementations that are provided by `kotlinx.coroutines`.
- * The [coroutineContext](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.coroutines.experimental/coroutine-context.html)
- * of the parent coroutine may be used,
- * in which case the [Job] of the resulting coroutine is a child of the job of the parent coroutine.
- * The parent job may be also explicitly specified using [parent] parameter.
- *
+ * 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 [DefaultDispatcher] is used.
+ * The parent job is inherited from a [CoroutineScope] as well, but it can also be overridden
+ * with corresponding [coroutineContext] element.
*
* By default, the coroutine is immediately scheduled for execution.
* Other options can be specified via `start` parameter. See [CoroutineStart] for details.
*
* @param context context of the coroutine. The default value is [DefaultDispatcher].
* @param start coroutine start option. The default value is [CoroutineStart.DEFAULT].
- * @param parent explicitly specifies the parent job, overrides job from the [context] (if any).
* @param onCompletion optional completion handler for the coroutine (see [Job.invokeOnCompletion]).
* @param block the coroutine code.
*/
+public fun <T> CoroutineScope.promise(
+ context: CoroutineContext = DefaultDispatcher,
+ start: CoroutineStart = CoroutineStart.DEFAULT,
+ onCompletion: CompletionHandler? = null,
+ block: suspend CoroutineScope.() -> T
+): Promise<T> =
+ async(context, start, onCompletion, block = block).asPromise()
+
+/**
+ * Starts new coroutine and returns its result as an implementation of [Promise].
+ * @suppress **Deprecated**. Use [CoroutineScope.promise] instead.
+ */
+@Deprecated(
+ message = "Standalone coroutine builders are deprecated, use extensions on CoroutineScope instead",
+ replaceWith = ReplaceWith("GlobalScope.promise(context + parent, start, onCompletion, block)",
+ imports = ["kotlinx.coroutines.experimental.*"])
+)
+public fun <T> promise(
+ context: CoroutineContext = DefaultDispatcher,
+ start: CoroutineStart = CoroutineStart.DEFAULT,
+ onCompletion: CompletionHandler? = null,
+ block: suspend CoroutineScope.() -> T
+): Promise<T> =
+ GlobalScope.promise(context, start, onCompletion, block = block)
+
+/**
+ * Starts new coroutine and returns its result as an implementation of [Promise].
+ * @suppress **Deprecated**. Use [CoroutineScope.promise] instead.
+ */
+@Deprecated(
+ message = "Standalone coroutine builders are deprecated, use extensions on CoroutineScope instead",
+ replaceWith = ReplaceWith("GlobalScope.promise(context + parent, start, onCompletion, block)",
+ imports = ["kotlinx.coroutines.experimental.*"])
+)
public fun <T> promise(
context: CoroutineContext = DefaultDispatcher,
start: CoroutineStart = CoroutineStart.DEFAULT,
@@ -35,7 +64,7 @@
onCompletion: CompletionHandler? = null,
block: suspend CoroutineScope.() -> T
): Promise<T> =
- GlobalScope.async(context + (parent ?: EmptyCoroutineContext), start, onCompletion, block = block).asPromise()
+ GlobalScope.promise(context + (parent ?: EmptyCoroutineContext), start, onCompletion, block = block)
/**
* Converts this deferred value to the instance of [Promise].
diff --git a/js/kotlinx-coroutines-core-js/test/PromiseTest.kt b/js/kotlinx-coroutines-core-js/test/PromiseTest.kt
index 0398b1d..2e165c1 100644
--- a/js/kotlinx-coroutines-core-js/test/PromiseTest.kt
+++ b/js/kotlinx-coroutines-core-js/test/PromiseTest.kt
@@ -10,7 +10,7 @@
class PromiseTest : TestBase() {
@Test
- fun testPromiseResolvedAsDeferred() = promise {
+ fun testPromiseResolvedAsDeferred() = GlobalScope.promise {
val promise = Promise<String> { resolve, _ ->
resolve("OK")
}
@@ -19,7 +19,7 @@
}
@Test
- fun testPromiseRejectedAsDeferred() = promise {
+ fun testPromiseRejectedAsDeferred() = GlobalScope.promise {
lateinit var promiseReject: (Throwable) -> Unit
val promise = Promise<String> { _, reject ->
promiseReject = reject
@@ -37,7 +37,7 @@
}
@Test
- fun testCompletedDeferredAsPromise() = promise {
+ fun testCompletedDeferredAsPromise() = GlobalScope.promise {
val deferred = async(coroutineContext, CoroutineStart.UNDISPATCHED) {
// completed right away
"OK"
@@ -47,7 +47,7 @@
}
@Test
- fun testWaitForDeferredAsPromise() = promise {
+ fun testWaitForDeferredAsPromise() = GlobalScope.promise {
val deferred = async(coroutineContext) {
// will complete later
"OK"
@@ -57,7 +57,7 @@
}
@Test
- fun testCancellableAwaitPromise() = promise {
+ fun testCancellableAwaitPromise() = GlobalScope.promise {
lateinit var r: (String) -> Unit
val toAwait = Promise<String> { resolve, _ -> r = resolve }
val job = launch(coroutineContext, CoroutineStart.UNDISPATCHED) {
@@ -68,7 +68,7 @@
}
@Test
- fun testAsPromiseAsDeferred() = promise {
+ fun testAsPromiseAsDeferred() = GlobalScope.promise {
val deferred = async { "OK" }
val promise = deferred.asPromise()
val d2 = promise.asDeferred()
diff --git a/js/kotlinx-coroutines-core-js/test/TestBase.kt b/js/kotlinx-coroutines-core-js/test/TestBase.kt
index 8db40db..473f279 100644
--- a/js/kotlinx-coroutines-core-js/test/TestBase.kt
+++ b/js/kotlinx-coroutines-core-js/test/TestBase.kt
@@ -72,7 +72,7 @@
): dynamic {
var exCount = 0
var ex: Throwable? = null
- return promise(block = block, context = CoroutineExceptionHandler { context, e ->
+ return GlobalScope.promise(block = block, context = CoroutineExceptionHandler { context, e ->
if (e is CancellationException) return@CoroutineExceptionHandler // are ignored
exCount++
when {
diff --git a/native/kotlinx-coroutines-core-native/src/Builders.kt b/native/kotlinx-coroutines-core-native/src/Builders.kt
index 50d8185..4abdbd0 100644
--- a/native/kotlinx-coroutines-core-native/src/Builders.kt
+++ b/native/kotlinx-coroutines-core-native/src/Builders.kt
@@ -38,7 +38,7 @@
newEventLoop
} else
contextInterceptor as? EventLoop
- val newContext = newCoroutineContext(
+ val newContext = GlobalScope.newCoroutineContext(
if (privateEventLoop) context + (eventLoop as ContinuationInterceptor) else context
)
val coroutine = BlockingCoroutine<T>(newContext, eventLoop, privateEventLoop)
diff --git a/native/kotlinx-coroutines-core-native/src/CoroutineContext.kt b/native/kotlinx-coroutines-core-native/src/CoroutineContext.kt
index ae6fb02..c90e23a 100644
--- a/native/kotlinx-coroutines-core-native/src/CoroutineContext.kt
+++ b/native/kotlinx-coroutines-core-native/src/CoroutineContext.kt
@@ -41,15 +41,10 @@
internal actual val DefaultDelay: Delay = DefaultExecutor
-/**
- * Creates context for the new coroutine. It installs [DefaultDispatcher] when no other dispatcher nor
- * [ContinuationInterceptor] is specified, and adds optional support for debugging facilities (when turned on).
- */
-@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
-public actual fun newCoroutineContext(context: CoroutineContext, parent: Job? = null): CoroutineContext {
- val wp = if (parent == null) context else context + parent
- return if (context !== DefaultDispatcher && context[ContinuationInterceptor] == null)
- wp + DefaultDispatcher else wp
+public actual fun CoroutineScope.newCoroutineContext(context: CoroutineContext): CoroutineContext {
+ val combined = coroutineContext + context
+ return if (combined !== kotlinx.coroutines.experimental.DefaultDispatcher && combined[ContinuationInterceptor] == null)
+ combined + kotlinx.coroutines.experimental.DefaultDispatcher else combined
}
// No debugging facilities on native
diff --git a/ui/coroutines-guide-ui.md b/ui/coroutines-guide-ui.md
index 05325b3..781cb02 100644
--- a/ui/coroutines-guide-ui.md
+++ b/ui/coroutines-guide-ui.md
@@ -468,7 +468,7 @@
The natural solution to this problem is to associate a [Job] object with each UI object that has a lifecycle and create
all the coroutines in the context of this job. But passing associated job object to every coroutine builder is error-prone,
it is easy to forget it. For this purpose, [CoroutineScope] interface should be implemented by UI owner, and then every
-coroutine builder defined as an extension on [CoroutineScope] will inherit UI job without explicit mentioning.
+coroutine builder defined as an extension on [CoroutineScope] inherits UI job without explicitly mentioning it.
For example, in Android application an `Activity` is initially _created_ and is _destroyed_ when it is no longer
needed and when its memory must be released. A natural solution is to attach an
@@ -477,8 +477,9 @@
```kotlin
abstract class ScopedAppActivity: AppCompatActivity(), CoroutineScope {
- override val coroutineContext: CoroutineContext by lazy { job + UI }
protected lateinit var job: Job
+ override val coroutineContext: CoroutineContext
+ get() = job + UI
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -513,7 +514,7 @@
}
```
-Every coroutine launched from within a `MainActivity` will have its job as a parent and will be cancelled if
+Every coroutine launched from within a `MainActivity` has its job as a parent and is immediately cancelled when
activity is destroyed.
To propagate activity scope to its views and presenters, one can use [currentScope] builder which captures current