@@ -18,17 +18,13 @@ import kotlin.coroutines.experimental.intrinsics.*
18
18
* Launches new coroutine without blocking current thread and returns a reference to the coroutine as a [Job].
19
19
* The coroutine is cancelled when the resulting job is [cancelled][Job.cancel].
20
20
*
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.
28
22
* 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.
29
25
*
30
26
* 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.
32
28
* An optional [start] parameter can be set to [CoroutineStart.LAZY] to start coroutine _lazily_. In this case,
33
29
* the coroutine [Job] is created in _new_ state. It can be explicitly started with [start][Job.start] function
34
30
* and will be started implicitly on the first invocation of [join][Job.join].
@@ -39,35 +35,68 @@ import kotlin.coroutines.experimental.intrinsics.*
39
35
*
40
36
* See [newCoroutineContext] for a description of debugging facilities that are available for newly created coroutine.
41
37
*
42
- * @param context context of the coroutine. The default value is [DefaultDispatcher].
38
+ * @param context additional to [CoroutineScope.coroutineContext] context of the coroutine
43
39
* @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).
45
40
* @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 ,
50
45
start : CoroutineStart = CoroutineStart .DEFAULT ,
51
- parent : Job ? = null,
52
46
onCompletion : CompletionHandler ? = null,
53
47
block : suspend CoroutineScope .() -> Unit
54
48
): Job {
55
- val newContext = newCoroutineContext(context, parent )
49
+ val newContext = newCoroutineContext(context)
56
50
val coroutine = if (start.isLazy)
57
51
LazyStandaloneCoroutine (newContext, block) else
58
52
StandaloneCoroutine (newContext, active = true )
59
53
if (onCompletion != null ) coroutine.invokeOnCompletion(handler = onCompletion)
60
54
coroutine.start(start, coroutine, block)
61
55
return coroutine
62
56
}
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
+
63
91
/* * @suppress **Deprecated**: Binary compatibility */
64
92
@Deprecated(message = " Binary compatibility" , level = DeprecationLevel .HIDDEN )
65
93
public fun launch (
66
94
context : CoroutineContext = DefaultDispatcher ,
67
95
start : CoroutineStart = CoroutineStart .DEFAULT ,
68
96
parent : Job ? = null,
69
97
block : suspend CoroutineScope .() -> Unit
70
- ): Job = launch(context, start, parent, block = block)
98
+ ): Job =
99
+ GlobalScope .launch(context + (parent ? : EmptyCoroutineContext ), start, block = block)
71
100
72
101
/* * @suppress **Deprecated**: Binary compatibility */
73
102
@Deprecated(message = " Binary compatibility" , level = DeprecationLevel .HIDDEN )
@@ -84,7 +113,7 @@ public fun launch(
84
113
@Deprecated(message = " Use `start = CoroutineStart.XXX` parameter" ,
85
114
replaceWith = ReplaceWith (" launch(context, if (start) CoroutineStart.DEFAULT else CoroutineStart.LAZY, block)" ))
86
115
public 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)
88
117
89
118
/* *
90
119
* 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
103
132
* A value of [CoroutineStart.LAZY] is not supported and produces [IllegalArgumentException].
104
133
*/
105
134
public 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 (
106
148
context : CoroutineContext ,
107
149
start : CoroutineStart = CoroutineStart .DEFAULT ,
108
150
block : suspend () -> T
@@ -137,6 +179,16 @@ public suspend fun <T> withContext(
137
179
completion.getResult()
138
180
}
139
181
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
+
140
192
/* * @suppress **Deprecated**: Renamed to [withContext]. */
141
193
@Deprecated(message = " Renamed to `withContext`" , level= DeprecationLevel .WARNING ,
142
194
replaceWith = ReplaceWith (" withContext(context, start, block)" ))
@@ -145,12 +197,12 @@ public suspend fun <T> run(
145
197
start : CoroutineStart = CoroutineStart .DEFAULT ,
146
198
block : suspend () -> T
147
199
): T =
148
- withContext (context, start, block)
200
+ withContextImpl (context, start, block)
149
201
150
202
/* * @suppress **Deprecated** */
151
203
@Deprecated(message = " It is here for binary compatibility only" , level= DeprecationLevel .HIDDEN )
152
204
public 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)
154
206
155
207
// --------------- implementation ---------------
156
208
0 commit comments