1 /* <lambda>null2 * Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 */ 4 5 package kotlinx.coroutines 6 7 private const val WAIT_LOST_THREADS = 10_000L // 10s 8 private val ignoreLostThreads = mutableSetOf<String>() 9 10 fun ignoreLostThreads(vararg s: String) { ignoreLostThreads += s } 11 currentThreadsnull12fun currentThreads(): Set<Thread> { 13 var estimate = 0 14 while (true) { 15 estimate = estimate.coerceAtLeast(Thread.activeCount() + 1) 16 val arrayOfThreads = Array<Thread?>(estimate) { null } 17 val n = Thread.enumerate(arrayOfThreads) 18 if (n >= estimate) { 19 estimate = n + 1 20 continue // retry with a better size estimate 21 } 22 val threads = hashSetOf<Thread>() 23 for (i in 0 until n) 24 threads.add(arrayOfThreads[i]!!) 25 return threads 26 } 27 } 28 dumpThreadsnull29fun List<Thread>.dumpThreads(header: String) { 30 println("=== $header") 31 forEach { thread -> 32 println("Thread \"${thread.name}\" ${thread.state}") 33 val trace = thread.stackTrace 34 for (t in trace) println("\tat ${t.className}.${t.methodName}(${t.fileName}:${t.lineNumber})") 35 println() 36 } 37 println("===") 38 } 39 dumpThreadsnull40fun ExecutorCoroutineDispatcher.dumpThreads(header: String) = 41 currentThreads().filter { it is PoolThread && it.dispatcher == this@dumpThreads }.dumpThreads(header) 42 checkTestThreadsnull43fun checkTestThreads(threadsBefore: Set<Thread>) { 44 // give threads some time to shutdown 45 val waitTill = System.currentTimeMillis() + WAIT_LOST_THREADS 46 var diff: List<Thread> 47 do { 48 val threadsAfter = currentThreads() 49 diff = (threadsAfter - threadsBefore).filter { thread -> 50 ignoreLostThreads.none { prefix -> thread.name.startsWith(prefix) } 51 } 52 if (diff.isEmpty()) break 53 } while (System.currentTimeMillis() <= waitTill) 54 ignoreLostThreads.clear() 55 if (diff.isEmpty()) return 56 val message = "Lost threads ${diff.map { it.name }}" 57 println("!!! $message") 58 diff.dumpThreads("Dumping lost thread stack traces") 59 error(message) 60 } 61