Skip to content

Commit 560cd72

Browse files
qwwdfsadelizarov
authored andcommitted
Properly implement select clause for JS channels
1 parent 8165d4e commit 560cd72

File tree

7 files changed

+140
-58
lines changed

7 files changed

+140
-58
lines changed

common/kotlinx-coroutines-core-common/src/main/kotlin/kotlinx/coroutines/experimental/internal/Atomic.kt

+3-1
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,10 @@ public abstract class AtomicOp<in T> : OpDescriptor() {
6666
final override fun perform(affected: Any?): Any? {
6767
// make decision on status
6868
var decision = this._consensus.value
69-
if (decision === NO_DECISION)
69+
if (decision === NO_DECISION) {
7070
decision = decide(prepare(affected as T))
71+
}
72+
7173
complete(affected as T, decision)
7274
return decision
7375
}

common/kotlinx-coroutines-core-common/src/test/kotlin/kotlinx/coroutines/experimental/channels/ConflatedBroadcastChannelTest.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ class ConflatedBroadcastChannelTest : TestBase() {
116116
}
117117
}
118118

119-
// Ugly workaround for bug in JS compiler
119+
// Workaround for KT-23921
120120
fun exceptionFromNotInline(block: () -> Unit): Throwable? {
121121
try {
122122
block()
+21-21
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ package kotlinx.coroutines.experimental.selects
1919
import kotlinx.coroutines.experimental.*
2020
import kotlinx.coroutines.experimental.channels.*
2121
import kotlinx.coroutines.experimental.intrinsics.*
22-
import org.junit.*
23-
import org.junit.Assert.*
2422
import kotlin.coroutines.experimental.*
23+
import kotlin.test.*
2524

2625
class SelectArrayChannelTest : TestBase() {
26+
2727
@Test
28-
fun testSelectSendSuccess() = runBlocking<Unit> {
28+
fun testSelectSendSuccess() = runTest {
2929
expect(1)
3030
val channel = ArrayChannel<String>(1)
3131
launch(coroutineContext) {
@@ -44,7 +44,7 @@ class SelectArrayChannelTest : TestBase() {
4444
}
4545

4646
@Test
47-
fun testSelectSendSuccessWithDefault() = runBlocking<Unit> {
47+
fun testSelectSendSuccessWithDefault() = runTest {
4848
expect(1)
4949
val channel = ArrayChannel<String>(1)
5050
launch(coroutineContext) {
@@ -66,7 +66,7 @@ class SelectArrayChannelTest : TestBase() {
6666
}
6767

6868
@Test
69-
fun testSelectSendReceiveBuf() = runBlocking<Unit> {
69+
fun testSelectSendReceiveBuf() = runTest {
7070
expect(1)
7171
val channel = ArrayChannel<String>(1)
7272
select<Unit> {
@@ -85,7 +85,7 @@ class SelectArrayChannelTest : TestBase() {
8585
}
8686

8787
@Test
88-
fun testSelectSendWait() = runBlocking<Unit> {
88+
fun testSelectSendWait() = runTest {
8989
expect(1)
9090
val channel = ArrayChannel<String>(1)
9191
launch(coroutineContext) {
@@ -107,7 +107,7 @@ class SelectArrayChannelTest : TestBase() {
107107
}
108108

109109
@Test
110-
fun testSelectReceiveSuccess() = runBlocking<Unit> {
110+
fun testSelectReceiveSuccess() = runTest {
111111
expect(1)
112112
val channel = ArrayChannel<String>(1)
113113
channel.send("OK")
@@ -122,7 +122,7 @@ class SelectArrayChannelTest : TestBase() {
122122
}
123123

124124
@Test
125-
fun testSelectReceiveSuccessWithDefault() = runBlocking<Unit> {
125+
fun testSelectReceiveSuccessWithDefault() = runTest {
126126
expect(1)
127127
val channel = ArrayChannel<String>(1)
128128
channel.send("OK")
@@ -140,7 +140,7 @@ class SelectArrayChannelTest : TestBase() {
140140
}
141141

142142
@Test
143-
fun testSelectReceiveWaitWithDefault() = runBlocking<Unit> {
143+
fun testSelectReceiveWaitWithDefault() = runTest {
144144
expect(1)
145145
val channel = ArrayChannel<String>(1)
146146
select<Unit> {
@@ -170,7 +170,7 @@ class SelectArrayChannelTest : TestBase() {
170170
}
171171

172172
@Test
173-
fun testSelectReceiveWait() = runBlocking<Unit> {
173+
fun testSelectReceiveWait() = runTest {
174174
expect(1)
175175
val channel = ArrayChannel<String>(1)
176176
launch(coroutineContext) {
@@ -188,8 +188,8 @@ class SelectArrayChannelTest : TestBase() {
188188
finish(6)
189189
}
190190

191-
@Test(expected = ClosedReceiveChannelException::class)
192-
fun testSelectReceiveClosed() = runBlocking<Unit> {
191+
@Test
192+
fun testSelectReceiveClosed() = runTest({it is ClosedReceiveChannelException}) {
193193
expect(1)
194194
val channel = ArrayChannel<String>(1)
195195
channel.close()
@@ -202,8 +202,8 @@ class SelectArrayChannelTest : TestBase() {
202202
expectUnreached()
203203
}
204204

205-
@Test(expected = ClosedReceiveChannelException::class)
206-
fun testSelectReceiveWaitClosed() = runBlocking<Unit> {
205+
@Test
206+
fun testSelectReceiveWaitClosed() = runTest({it is ClosedReceiveChannelException}) {
207207
expect(1)
208208
val channel = ArrayChannel<String>(1)
209209
launch(coroutineContext) {
@@ -221,9 +221,9 @@ class SelectArrayChannelTest : TestBase() {
221221
}
222222

223223
@Test
224-
fun testSelectSendResourceCleanup() = runBlocking<Unit> {
224+
fun testSelectSendResourceCleanup() = runTest {
225225
val channel = ArrayChannel<Int>(1)
226-
val n = 10_000_000 * stressTestMultiplier
226+
val n = 1000
227227
expect(1)
228228
channel.send(-1) // fill the buffer, so all subsequent sends cannot proceed
229229
repeat(n) { i ->
@@ -236,9 +236,9 @@ class SelectArrayChannelTest : TestBase() {
236236
}
237237

238238
@Test
239-
fun testSelectReceiveResourceCleanup() = runBlocking<Unit> {
239+
fun testSelectReceiveResourceCleanup() = runTest {
240240
val channel = ArrayChannel<Int>(1)
241-
val n = 10_000_000 * stressTestMultiplier
241+
val n = 1000
242242
expect(1)
243243
repeat(n) { i ->
244244
select {
@@ -250,7 +250,7 @@ class SelectArrayChannelTest : TestBase() {
250250
}
251251

252252
@Test
253-
fun testSelectReceiveDispatchNonSuspending() = runBlocking<Unit> {
253+
fun testSelectReceiveDispatchNonSuspending() = runTest {
254254
val channel = ArrayChannel<Int>(1)
255255
expect(1)
256256
channel.send(42)
@@ -272,7 +272,7 @@ class SelectArrayChannelTest : TestBase() {
272272
}
273273

274274
@Test
275-
fun testSelectReceiveDispatchNonSuspending2() = runBlocking<Unit> {
275+
fun testSelectReceiveDispatchNonSuspending2() = runTest {
276276
val channel = ArrayChannel<Int>(1)
277277
expect(1)
278278
channel.send(42)
@@ -303,4 +303,4 @@ class SelectArrayChannelTest : TestBase() {
303303
if (!trySelect(null)) return
304304
block.startCoroutineUndispatched(this)
305305
}
306-
}
306+
}

core/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/selects/SelectBiasTest.kt renamed to common/kotlinx-coroutines-core-common/src/test/kotlin/kotlinx/coroutines/experimental/selects/SelectBiasTest.kt

+4-5
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,14 @@
1717
package kotlinx.coroutines.experimental.selects
1818

1919
import kotlinx.coroutines.experimental.*
20-
import org.junit.*
21-
import org.junit.Assert.*
2220
import kotlin.coroutines.experimental.*
21+
import kotlin.test.*
2322

24-
class SelectBiasTest {
23+
class SelectBiasTest : TestBase() {
2524
val n = 10_000
2625

2726
@Test
28-
fun testBiased() = runBlocking<Unit> {
27+
fun testBiased() = runTest {
2928
val d0 = async(coroutineContext) { 0 }
3029
val d1 = async(coroutineContext) { 1 }
3130
val counter = IntArray(2)
@@ -41,7 +40,7 @@ class SelectBiasTest {
4140
}
4241

4342
@Test
44-
fun testUnbiased() = runBlocking<Unit> {
43+
fun testUnbiased() = runTest {
4544
val d0 = async(coroutineContext) { 0 }
4645
val d1 = async(coroutineContext) { 1 }
4746
val counter = IntArray(2)
+22-21
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,20 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16+
@file:Suppress("NAMED_ARGUMENTS_NOT_ALLOWED") // KT-21913
1617

1718
package kotlinx.coroutines.experimental.selects
1819

1920
import kotlinx.coroutines.experimental.*
2021
import kotlinx.coroutines.experimental.channels.*
2122
import kotlinx.coroutines.experimental.intrinsics.*
22-
import org.junit.*
23-
import org.junit.Assert.*
2423
import kotlin.coroutines.experimental.*
24+
import kotlin.test.*
2525

2626
class SelectRendezvousChannelTest : TestBase() {
27+
2728
@Test
28-
fun testSelectSendSuccess() = runBlocking<Unit> {
29+
fun testSelectSendSuccess() = runTest {
2930
expect(1)
3031
val channel = RendezvousChannel<String>()
3132
launch(coroutineContext) {
@@ -44,7 +45,7 @@ class SelectRendezvousChannelTest : TestBase() {
4445
}
4546

4647
@Test
47-
fun testSelectSendSuccessWithDefault() = runBlocking<Unit> {
48+
fun testSelectSendSuccessWithDefault() = runTest {
4849
expect(1)
4950
val channel = RendezvousChannel<String>()
5051
launch(coroutineContext) {
@@ -66,7 +67,7 @@ class SelectRendezvousChannelTest : TestBase() {
6667
}
6768

6869
@Test
69-
fun testSelectSendWaitWithDefault() = runBlocking<Unit> {
70+
fun testSelectSendWaitWithDefault() = runTest {
7071
expect(1)
7172
val channel = RendezvousChannel<String>()
7273
select<Unit> {
@@ -92,7 +93,7 @@ class SelectRendezvousChannelTest : TestBase() {
9293
}
9394

9495
@Test
95-
fun testSelectSendWait() = runBlocking<Unit> {
96+
fun testSelectSendWait() = runTest {
9697
expect(1)
9798
val channel = RendezvousChannel<String>()
9899
launch(coroutineContext) {
@@ -110,7 +111,7 @@ class SelectRendezvousChannelTest : TestBase() {
110111
}
111112

112113
@Test
113-
fun testSelectReceiveSuccess() = runBlocking<Unit> {
114+
fun testSelectReceiveSuccess() = runTest {
114115
expect(1)
115116
val channel = RendezvousChannel<String>()
116117
launch(coroutineContext) {
@@ -130,7 +131,7 @@ class SelectRendezvousChannelTest : TestBase() {
130131
}
131132

132133
@Test
133-
fun testSelectReceiveSuccessWithDefault() = runBlocking<Unit> {
134+
fun testSelectReceiveSuccessWithDefault() = runTest {
134135
expect(1)
135136
val channel = RendezvousChannel<String>()
136137
launch(coroutineContext) {
@@ -153,7 +154,7 @@ class SelectRendezvousChannelTest : TestBase() {
153154
}
154155

155156
@Test
156-
fun testSelectReceiveWaitWithDefault() = runBlocking<Unit> {
157+
fun testSelectReceiveWaitWithDefault() = runTest {
157158
expect(1)
158159
val channel = RendezvousChannel<String>()
159160
select<Unit> {
@@ -179,7 +180,7 @@ class SelectRendezvousChannelTest : TestBase() {
179180
}
180181

181182
@Test
182-
fun testSelectReceiveWait() = runBlocking<Unit> {
183+
fun testSelectReceiveWait() = runTest {
183184
expect(1)
184185
val channel = RendezvousChannel<String>()
185186
launch(coroutineContext) {
@@ -197,8 +198,8 @@ class SelectRendezvousChannelTest : TestBase() {
197198
finish(6)
198199
}
199200

200-
@Test(expected = ClosedReceiveChannelException::class)
201-
fun testSelectReceiveClosed() = runBlocking<Unit> {
201+
@Test
202+
fun testSelectReceiveClosed() = runTest(expected = { it is ClosedReceiveChannelException }) {
202203
expect(1)
203204
val channel = RendezvousChannel<String>()
204205
channel.close()
@@ -211,8 +212,8 @@ class SelectRendezvousChannelTest : TestBase() {
211212
expectUnreached()
212213
}
213214

214-
@Test(expected = ClosedReceiveChannelException::class)
215-
fun testSelectReceiveWaitClosed() = runBlocking<Unit> {
215+
@Test
216+
fun testSelectReceiveWaitClosed() = runTest(expected = {it is ClosedReceiveChannelException}) {
216217
expect(1)
217218
val channel = RendezvousChannel<String>()
218219
launch(coroutineContext) {
@@ -230,9 +231,9 @@ class SelectRendezvousChannelTest : TestBase() {
230231
}
231232

232233
@Test
233-
fun testSelectSendResourceCleanup() = runBlocking<Unit> {
234+
fun testSelectSendResourceCleanup() = runTest {
234235
val channel = RendezvousChannel<Int>()
235-
val n = 10_000_000 * stressTestMultiplier
236+
val n = 1_000
236237
expect(1)
237238
repeat(n) { i ->
238239
select {
@@ -244,9 +245,9 @@ class SelectRendezvousChannelTest : TestBase() {
244245
}
245246

246247
@Test
247-
fun testSelectReceiveResourceCleanup() = runBlocking<Unit> {
248+
fun testSelectReceiveResourceCleanup() = runTest {
248249
val channel = RendezvousChannel<Int>()
249-
val n = 10_000_000 * stressTestMultiplier
250+
val n = 1_000
250251
expect(1)
251252
repeat(n) { i ->
252253
select {
@@ -258,7 +259,7 @@ class SelectRendezvousChannelTest : TestBase() {
258259
}
259260

260261
@Test
261-
fun testSelectAtomicFailure() = runBlocking<Unit> {
262+
fun testSelectAtomicFailure() = runTest {
262263
val c1 = RendezvousChannel<Int>()
263264
val c2 = RendezvousChannel<Int>()
264265
expect(1)
@@ -289,7 +290,7 @@ class SelectRendezvousChannelTest : TestBase() {
289290
}
290291

291292
@Test
292-
fun testSelectWaitDispatch() = runBlocking<Unit> {
293+
fun testSelectWaitDispatch() = runTest {
293294
val c = RendezvousChannel<Int>()
294295
expect(1)
295296
launch(coroutineContext) {
@@ -323,4 +324,4 @@ class SelectRendezvousChannelTest : TestBase() {
323324
if (!trySelect(null)) return
324325
block.startCoroutineUndispatched(this)
325326
}
326-
}
327+
}

0 commit comments

Comments
 (0)