aboutsummaryrefslogtreecommitdiffstats
path: root/kotlinx-coroutines-core/jvm/test/JobDisposeStressTest.kt
diff options
context:
space:
mode:
Diffstat (limited to 'kotlinx-coroutines-core/jvm/test/JobDisposeStressTest.kt')
-rw-r--r--kotlinx-coroutines-core/jvm/test/JobDisposeStressTest.kt80
1 files changed, 80 insertions, 0 deletions
diff --git a/kotlinx-coroutines-core/jvm/test/JobDisposeStressTest.kt b/kotlinx-coroutines-core/jvm/test/JobDisposeStressTest.kt
new file mode 100644
index 00000000..3a074f15
--- /dev/null
+++ b/kotlinx-coroutines-core/jvm/test/JobDisposeStressTest.kt
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package kotlinx.coroutines
+
+import org.junit.Test
+import kotlin.concurrent.thread
+
+/**
+ * Tests concurrent cancel & dispose of the jobs.
+ */
+class JobDisposeStressTest: TestBase() {
+ private val TEST_DURATION = 3 * stressTestMultiplier // seconds
+
+ @Volatile
+ private var done = false
+ @Volatile
+ private var job: TestJob? = null
+ @Volatile
+ private var handle: DisposableHandle? = null
+
+ @Volatile
+ private var exception: Throwable? = null
+
+ private fun testThread(name: String, block: () -> Unit): Thread =
+ thread(start = false, name = name, block = block).apply {
+ setUncaughtExceptionHandler { t, e ->
+ exception = e
+ println("Exception in ${t.name}: $e")
+ e.printStackTrace()
+ }
+ }
+
+ @Test
+ fun testConcurrentDispose() {
+ // create threads
+ val threads = mutableListOf<Thread>()
+ threads += testThread("creator") {
+ while (!done) {
+ val job = TestJob()
+ val handle = job.invokeOnCompletion(onCancelling = true) { /* nothing */ }
+ this.job = job // post job to cancelling thread
+ this.handle = handle // post handle to concurrent disposer thread
+ handle.dispose() // dispose of handle from this thread (concurrently with other disposer)
+ }
+ }
+
+ threads += testThread("canceller") {
+ while (!done) {
+ val job = this.job ?: continue
+ job.cancel()
+ // Always returns true, TestJob never completes
+ }
+ }
+
+ threads += testThread("disposer") {
+ while (!done) {
+ handle?.dispose()
+ }
+ }
+
+ // start threads
+ threads.forEach { it.start() }
+ // wait
+ for (i in 1..TEST_DURATION) {
+ println("$i: Running")
+ Thread.sleep(1000)
+ if (exception != null) break
+ }
+ // done
+ done = true
+ // join threads
+ threads.forEach { it.join() }
+ // rethrow exception if any
+ }
+
+ @Suppress("DEPRECATION_ERROR")
+ private class TestJob : JobSupport(active = true)
+} \ No newline at end of file