@@ -18,17 +18,13 @@ import kotlin.coroutines.experimental.intrinsics.*
1818 * Launches new coroutine without blocking current thread and returns a reference to the coroutine as a [Job].
1919 * The coroutine is cancelled when the resulting job is [cancelled][Job.cancel].
2020 *
21- * The [context] for the new coroutine can be explicitly specified.
22- * See [CoroutineDispatcher] for the standard context implementations that are provided by `kotlinx.coroutines`.
23- * The [coroutineContext](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.coroutines.experimental/coroutine-context.html)
24- * of the parent coroutine may be used,
25- * in which case the [Job] of the resulting coroutine is a child of the job of the parent coroutine.
26- * The parent job may be also explicitly specified using [parent] parameter.
27- *
21+ * Coroutine context is inherited from a [CoroutineScope], additional context elements can be specified with [context] argument.
2822 * If the context does not have any dispatcher nor any other [ContinuationInterceptor], then [DefaultDispatcher] is used.
23+ * The parent job is inherited from a [CoroutineScope] as well, but it can also be overridden
24+ * with corresponding [coroutineContext] element.
2925 *
3026 * By default, the coroutine is immediately scheduled for execution.
31- * Other options can be specified via `start` parameter. See [CoroutineStart] for details.
27+ * Other start options can be specified via `start` parameter. See [CoroutineStart] for details.
3228 * An optional [start] parameter can be set to [CoroutineStart.LAZY] to start coroutine _lazily_. In this case,
3329 * the coroutine [Job] is created in _new_ state. It can be explicitly started with [start][Job.start] function
3430 * and will be started implicitly on the first invocation of [join][Job.join].
@@ -39,35 +35,68 @@ import kotlin.coroutines.experimental.intrinsics.*
3935 *
4036 * See [newCoroutineContext] for a description of debugging facilities that are available for newly created coroutine.
4137 *
42- * @param context context of the coroutine. The default value is [DefaultDispatcher].
38+ * @param context additional to [CoroutineScope.coroutineContext] context of the coroutine
4339 * @param start coroutine start option. The default value is [CoroutineStart.DEFAULT].
44- * @param parent explicitly specifies the parent job, overrides job from the [context] (if any).
4540 * @param onCompletion optional completion handler for the coroutine (see [Job.invokeOnCompletion]).
46- * @param block the coroutine code.
47- */
48- public fun launch (
49- context : CoroutineContext = DefaultDispatcher ,
41+ * @param block the coroutine code which will be invoked in the context of the provided scope
42+ ** /
43+ public fun CoroutineScope. launch (
44+ context : CoroutineContext = EmptyCoroutineContext ,
5045 start : CoroutineStart = CoroutineStart .DEFAULT ,
51- parent : Job ? = null,
5246 onCompletion : CompletionHandler ? = null,
5347 block : suspend CoroutineScope .() -> Unit
5448): Job {
55- val newContext = newCoroutineContext(context, parent )
49+ val newContext = newCoroutineContext(context)
5650 val coroutine = if (start.isLazy)
5751 LazyStandaloneCoroutine (newContext, block) else
5852 StandaloneCoroutine (newContext, active = true )
5953 if (onCompletion != null ) coroutine.invokeOnCompletion(handler = onCompletion)
6054 coroutine.start(start, coroutine, block)
6155 return coroutine
6256}
57+
58+ /* *
59+ * Launches new coroutine without blocking current thread and returns a reference to the coroutine as a [Job].
60+ * @suppress **Deprecated** Use [CoroutineScope.launch] instead.
61+ */
62+ @Deprecated(
63+ message = " Standalone coroutine builders are deprecated, use extensions on CoroutineScope instead" ,
64+ replaceWith = ReplaceWith (" GlobalScope.launch(context, start, onCompletion, block)" , imports = [" kotlinx.coroutines.experimental.*" ])
65+ )
66+ public fun launch (
67+ context : CoroutineContext = DefaultDispatcher ,
68+ start : CoroutineStart = CoroutineStart .DEFAULT ,
69+ onCompletion : CompletionHandler ? = null,
70+ block : suspend CoroutineScope .() -> Unit
71+ ): Job =
72+ GlobalScope .launch(context, start, onCompletion, block)
73+
74+ /* *
75+ * Launches new coroutine without blocking current thread and returns a reference to the coroutine as a [Job].
76+ * @suppress **Deprecated** Use [CoroutineScope.launch] instead.
77+ */
78+ @Deprecated(
79+ message = " Standalone coroutine builders are deprecated, use extensions on CoroutineScope instead. This API will be hidden in the next release" ,
80+ replaceWith = ReplaceWith (" GlobalScope.launch(context + parent, start, onCompletion, block)" , imports = [" kotlinx.coroutines.experimental.*" ])
81+ )
82+ public fun launch (
83+ context : CoroutineContext = DefaultDispatcher ,
84+ start : CoroutineStart = CoroutineStart .DEFAULT ,
85+ parent : Job ? = null, // nullable for binary compatibility
86+ onCompletion : CompletionHandler ? = null,
87+ block : suspend CoroutineScope .() -> Unit
88+ ): Job =
89+ GlobalScope .launch(context + (parent ? : EmptyCoroutineContext ), start, onCompletion, block)
90+
6391/* * @suppress **Deprecated**: Binary compatibility */
6492@Deprecated(message = " Binary compatibility" , level = DeprecationLevel .HIDDEN )
6593public fun launch (
6694 context : CoroutineContext = DefaultDispatcher ,
6795 start : CoroutineStart = CoroutineStart .DEFAULT ,
6896 parent : Job ? = null,
6997 block : suspend CoroutineScope .() -> Unit
70- ): Job = launch(context, start, parent, block = block)
98+ ): Job =
99+ GlobalScope .launch(context + (parent ? : EmptyCoroutineContext ), start, block = block)
71100
72101/* * @suppress **Deprecated**: Binary compatibility */
73102@Deprecated(message = " Binary compatibility" , level = DeprecationLevel .HIDDEN )
@@ -84,7 +113,7 @@ public fun launch(
84113@Deprecated(message = " Use `start = CoroutineStart.XXX` parameter" ,
85114 replaceWith = ReplaceWith (" launch(context, if (start) CoroutineStart.DEFAULT else CoroutineStart.LAZY, block)" ))
86115public fun launch (context : CoroutineContext , start : Boolean , block : suspend CoroutineScope .() -> Unit ): Job =
87- launch(context, if (start) CoroutineStart .DEFAULT else CoroutineStart .LAZY , block = block)
116+ GlobalScope . launch(context, if (start) CoroutineStart .DEFAULT else CoroutineStart .LAZY , block = block)
88117
89118/* *
90119 * Calls the specified suspending block with a given coroutine context, suspends until it completes, and returns
@@ -103,6 +132,19 @@ public fun launch(context: CoroutineContext, start: Boolean, block: suspend Coro
103132 * A value of [CoroutineStart.LAZY] is not supported and produces [IllegalArgumentException].
104133 */
105134public suspend fun <T > withContext (
135+ context : CoroutineContext ,
136+ start : CoroutineStart = CoroutineStart .DEFAULT ,
137+ block : suspend CoroutineScope .() -> T
138+ ): T =
139+ // todo: optimize fast-path to work without allocation (when there is a already a coroutine implementing scope)
140+ withContextImpl(context, start) {
141+ currentScope {
142+ block()
143+ }
144+ }
145+
146+ // todo: optimize it to reduce allocations
147+ private suspend fun <T > withContextImpl (
106148 context : CoroutineContext ,
107149 start : CoroutineStart = CoroutineStart .DEFAULT ,
108150 block : suspend () -> T
@@ -137,6 +179,16 @@ public suspend fun <T> withContext(
137179 completion.getResult()
138180}
139181
182+ /* * @suppress **Deprecated**: Binary compatibility */
183+ @Deprecated(level = DeprecationLevel .HIDDEN , message = " Binary compatibility" )
184+ @JvmName(" withContext" )
185+ public suspend fun <T > withContext0 (
186+ context : CoroutineContext ,
187+ start : CoroutineStart = CoroutineStart .DEFAULT ,
188+ block : suspend () -> T
189+ ): T =
190+ withContextImpl(context, start, block)
191+
140192/* * @suppress **Deprecated**: Renamed to [withContext]. */
141193@Deprecated(message = " Renamed to `withContext`" , level= DeprecationLevel .WARNING ,
142194 replaceWith = ReplaceWith (" withContext(context, start, block)" ))
@@ -145,12 +197,12 @@ public suspend fun <T> run(
145197 start : CoroutineStart = CoroutineStart .DEFAULT ,
146198 block : suspend () -> T
147199): T =
148- withContext (context, start, block)
200+ withContextImpl (context, start, block)
149201
150202/* * @suppress **Deprecated** */
151203@Deprecated(message = " It is here for binary compatibility only" , level= DeprecationLevel .HIDDEN )
152204public suspend fun <T > run (context : CoroutineContext , block : suspend () -> T ): T =
153- withContext (context, start = CoroutineStart .ATOMIC , block = block)
205+ withContextImpl (context, start = CoroutineStart .ATOMIC , block = block)
154206
155207// --------------- implementation ---------------
156208
0 commit comments