-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Dispatchers.Default backed by pool of workers on Linux and by global_queue on iOS-like * Implementation of Dispatchers.Main that uses main queue on iOS and default dispatcher on other platforms (#2858) * Introduced newSingleThreadDispatcher and newFixedThreadPoolDispatcher * Use proper reentrant locking and CoW arrays on new memory model, make TestBase _almost_ race-free * More thread-safety in Native counterpart and one more test from native-mt * Source-set sharing for tests shared between JVM and K/N * Wrap Obj-C interop into autorelease pool to avoid memory leaks
- Loading branch information
Showing
66 changed files
with
1,157 additions
and
552 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
kotlinx-coroutines-core/concurrent/src/Builders.concurrent.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
/* | ||
* Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. | ||
*/ | ||
|
||
package kotlinx.coroutines | ||
|
||
import kotlin.coroutines.* | ||
|
||
/** | ||
* Runs a new coroutine and **blocks** the current thread until its completion. | ||
* This function should not be used from a coroutine. It is designed to bridge regular blocking code | ||
* to libraries that are written in suspending style, to be used in `main` functions and in tests. | ||
*/ | ||
public expect fun <T> runBlocking(context: CoroutineContext = EmptyCoroutineContext, block: suspend CoroutineScope.() -> T): T |
File renamed without changes.
23 changes: 23 additions & 0 deletions
23
kotlinx-coroutines-core/concurrent/src/MultithreadedDispatchers.common.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/* | ||
* Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. | ||
*/ | ||
|
||
package kotlinx.coroutines | ||
|
||
@ExperimentalCoroutinesApi | ||
public expect fun newSingleThreadContext(name: String): MultithreadedDispatcher | ||
|
||
@ExperimentalCoroutinesApi | ||
public expect fun newFixedThreadPoolContext(nThreads: Int, name: String): MultithreadedDispatcher | ||
|
||
/** | ||
* A coroutine dispatcher that is confined to a single thread. | ||
*/ | ||
@ExperimentalCoroutinesApi | ||
public expect abstract class MultithreadedDispatcher : CoroutineDispatcher { | ||
|
||
/** | ||
* Closes this coroutine dispatcher and shuts down its thread. | ||
*/ | ||
public abstract fun close() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54 changes: 54 additions & 0 deletions
54
kotlinx-coroutines-core/concurrent/test/AbstractDispatcherConcurrencyTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package kotlinx.coroutines | ||
|
||
import kotlinx.coroutines.channels.* | ||
import kotlin.test.* | ||
|
||
/* | ||
* Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. | ||
*/ | ||
|
||
abstract class AbstractDispatcherConcurrencyTest : TestBase() { | ||
|
||
public abstract val dispatcher: CoroutineDispatcher | ||
|
||
@Test | ||
fun testLaunchAndJoin() { | ||
expect(1) | ||
var capturedMutableState = 0 | ||
val job = GlobalScope.launch(dispatcher) { | ||
++capturedMutableState | ||
expect(2) | ||
} | ||
runBlocking { job.join() } | ||
assertEquals(1, capturedMutableState) | ||
finish(3) | ||
} | ||
|
||
@Test | ||
fun testDispatcherIsActuallyMultithreaded() { | ||
val channel = Channel<Int>() | ||
GlobalScope.launch(dispatcher) { | ||
channel.send(42) | ||
} | ||
|
||
var result = ChannelResult.failure<Int>() | ||
while (!result.isSuccess) { | ||
result = channel.tryReceive() | ||
// Block the thread, wait | ||
} | ||
// Delivery was successful, let's check it | ||
assertEquals(42, result.getOrThrow()) | ||
} | ||
|
||
@Test | ||
fun testDelayInDefaultDispatcher() { | ||
expect(1) | ||
val job = GlobalScope.launch(dispatcher) { | ||
expect(2) | ||
delay(100) | ||
expect(3) | ||
} | ||
runBlocking { job.join() } | ||
finish(4) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 65 additions & 0 deletions
65
kotlinx-coroutines-core/concurrent/test/ConcurrentExceptionsStressTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* | ||
* Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. | ||
*/ | ||
|
||
package kotlinx.coroutines | ||
|
||
import kotlinx.coroutines.exceptions.* | ||
import kotlin.test.* | ||
|
||
class ConcurrentExceptionsStressTest : TestBase() { | ||
private val nWorkers = 4 | ||
private val nRepeat = 1000 * stressTestMultiplier | ||
|
||
private val workers = Array(nWorkers) { index -> | ||
newSingleThreadContext("JobExceptionsStressTest-$index") | ||
} | ||
|
||
@AfterTest | ||
fun tearDown() { | ||
workers.forEach { | ||
it.close() | ||
} | ||
} | ||
|
||
@Test | ||
fun testStress() = runTest { | ||
repeat(nRepeat) { | ||
testOnce() | ||
} | ||
} | ||
|
||
@Suppress("SuspendFunctionOnCoroutineScope") // workaround native inline fun stacktraces | ||
private suspend fun CoroutineScope.testOnce() { | ||
val deferred = async(NonCancellable) { | ||
repeat(nWorkers) { index -> | ||
// Always launch a coroutine even if parent job was already cancelled (atomic start) | ||
launch(workers[index], start = CoroutineStart.ATOMIC) { | ||
randomWait() | ||
throw StressException(index) | ||
} | ||
} | ||
} | ||
deferred.join() | ||
assertTrue(deferred.isCancelled) | ||
val completionException = deferred.getCompletionExceptionOrNull() | ||
val cause = completionException as? StressException | ||
?: unexpectedException("completion", completionException) | ||
val suppressed = cause.suppressed | ||
val indices = listOf(cause.index) + suppressed.mapIndexed { index, e -> | ||
(e as? StressException)?.index ?: unexpectedException("suppressed $index", e) | ||
} | ||
repeat(nWorkers) { index -> | ||
assertTrue(index in indices, "Exception $index is missing: $indices") | ||
} | ||
assertEquals(nWorkers, indices.size, "Duplicated exceptions in list: $indices") | ||
} | ||
|
||
private fun unexpectedException(msg: String, e: Throwable?): Nothing { | ||
e?.printStackTrace() | ||
throw IllegalStateException("Unexpected $msg exception", e) | ||
} | ||
|
||
private class StressException(val index: Int) : SuppressSupportingThrowable() | ||
} | ||
|
23 changes: 23 additions & 0 deletions
23
kotlinx-coroutines-core/concurrent/test/ConcurrentTestUtilities.common.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/* | ||
* Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. | ||
*/ | ||
|
||
package kotlinx.coroutines.exceptions | ||
|
||
import kotlinx.coroutines.* | ||
|
||
internal expect open class SuppressSupportingThrowable() : Throwable | ||
expect val Throwable.suppressed: Array<Throwable> | ||
expect fun Throwable.printStackTrace() | ||
|
||
expect fun randomWait() | ||
|
||
expect fun currentThreadName(): String | ||
|
||
inline fun MultithreadedDispatcher.use(block: (MultithreadedDispatcher) -> Unit) { | ||
try { | ||
block(this) | ||
} finally { | ||
close() | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
kotlinx-coroutines-core/concurrent/test/DefaultDispatcherConcurrencyTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/* | ||
* Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. | ||
*/ | ||
package kotlinx.coroutines | ||
|
||
class DefaultDispatcherConcurrencyTest : AbstractDispatcherConcurrencyTest() { | ||
override val dispatcher: CoroutineDispatcher = Dispatchers.Default | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.