File tree 2 files changed +23
-3
lines changed
core/kotlinx-coroutines-core
2 files changed +23
-3
lines changed Original file line number Diff line number Diff line change @@ -300,6 +300,14 @@ internal class CoroutineScheduler(
300
300
fun shutdown (timeout : Long ) {
301
301
// atomically set termination flag which is checked when workers are added or removed
302
302
if (! isTerminated.compareAndSet(false , true )) return
303
+
304
+ /*
305
+ * Shutdown current thread. Note that shutdown is testing utility,
306
+ * so we don't do anything special to properly verify that no tasks are submitted after close()
307
+ */
308
+ val thread = Thread .currentThread()
309
+ (thread as ? Worker )?.tryReleaseCpu(WorkerState .TERMINATED )
310
+
303
311
// Capture # of created workers that cannot change anymore (mind the synchronized block!)
304
312
val created = synchronized(workers) { createdWorkers }
305
313
for (i in 1 .. created) {
@@ -653,7 +661,7 @@ internal class CoroutineScheduler(
653
661
* Releases CPU token if worker has any and changes state to [newState]
654
662
* @return whether worker had CPU token
655
663
*/
656
- private fun tryReleaseCpu (newState : WorkerState ): Boolean {
664
+ internal fun tryReleaseCpu (newState : WorkerState ): Boolean {
657
665
val previousState = state
658
666
val hadCpu = previousState == WorkerState .CPU_ACQUIRED
659
667
if (hadCpu) cpuPermits.release()
Original file line number Diff line number Diff line change 5
5
package kotlinx.coroutines.experimental.scheduling
6
6
7
7
import kotlinx.coroutines.experimental.TestBase
8
- import org.junit.Test
9
- import java.util.concurrent.CountDownLatch
8
+ import org.junit.*
9
+ import java.lang.Runnable
10
+ import java.util.concurrent.*
11
+ import kotlin.coroutines.experimental.*
10
12
11
13
class CoroutineSchedulerTest : TestBase () {
12
14
@@ -115,6 +117,16 @@ class CoroutineSchedulerTest : TestBase() {
115
117
ExperimentalCoroutineDispatcher (4 , 1 )
116
118
}
117
119
120
+ @Test
121
+ fun testSelfClose () {
122
+ val dispatcher = ExperimentalCoroutineDispatcher (1 , 1 )
123
+ val latch = CountDownLatch (1 )
124
+ dispatcher.dispatch(EmptyCoroutineContext , Runnable {
125
+ dispatcher.close(); latch.countDown()
126
+ })
127
+ latch.await()
128
+ }
129
+
118
130
private fun testUniformDistribution (worker : CoroutineScheduler .Worker , bound : Int ) {
119
131
val result = IntArray (bound)
120
132
val iterations = 10_000_000
You can’t perform that action at this time.
0 commit comments