1 /*
2 * Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3 */
4
5 package kotlinx.coroutines // Trick to make guide tests use these declarations with executors that can be closed on our side implicitly
6
7 import java.util.concurrent.*
8 import java.util.concurrent.atomic.*
9 import kotlin.coroutines.*
10
newSingleThreadContextnull11 internal fun newSingleThreadContext(name: String): ExecutorCoroutineDispatcher = ClosedAfterGuideTestDispatcher(1, name)
12
13 internal fun newFixedThreadPoolContext(nThreads: Int, name: String): ExecutorCoroutineDispatcher =
14 ClosedAfterGuideTestDispatcher(nThreads, name)
15
16 internal class PoolThread(
17 @JvmField val dispatcher: ExecutorCoroutineDispatcher, // for debugging & tests
18 target: Runnable, name: String
19 ) : Thread(target, name) {
20 init {
21 isDaemon = true
22 }
23 }
24
25 private class ClosedAfterGuideTestDispatcher(
26 private val nThreads: Int,
27 private val name: String
28 ) : ExecutorCoroutineDispatcher() {
29 private val threadNo = AtomicInteger()
30
31 override val executor: Executor =
32 Executors.newScheduledThreadPool(nThreads, object : ThreadFactory {
newThreadnull33 override fun newThread(target: java.lang.Runnable): Thread {
34 return PoolThread(
35 this@ClosedAfterGuideTestDispatcher,
36 target,
37 if (nThreads == 1) name else name + "-" + threadNo.incrementAndGet()
38 )
39 }
40 })
41
dispatchnull42 override fun dispatch(context: CoroutineContext, block: Runnable) {
43 executor.execute(wrapTask(block))
44 }
45
closenull46 override fun close() {
47 (executor as ExecutorService).shutdown()
48 }
49
toStringnull50 override fun toString(): String = "ThreadPoolDispatcher[$nThreads, $name]"
51 }
52