All Downloads are FREE. Search and download functionalities are using the official Maven repository.

posixMain.io.ktor.util.ThreadInfo.kt Maven / Gradle / Ivy

Go to download

Ktor is a framework for quickly creating web applications in Kotlin with minimal effort.

There is a newer version: 3.0.0-rc-1
Show newest version
/*
 * Copyright 2014-2022 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
 */

package io.ktor.util

import io.ktor.util.collections.*
import kotlinx.cinterop.*
import platform.posix.*
import kotlin.experimental.*
import kotlin.native.concurrent.*

@Suppress("DEPRECATION")
@OptIn(ExperimentalStdlibApi::class)
@EagerInitialization
private val init = setSignalHandler()

@InternalAPI
public object ThreadInfo {
    private val threads = ConcurrentMap(initialCapacity = 32)

    init {
        init
    }

    public fun registerCurrentThread() {
        @Suppress("UNNECESSARY_NOT_NULL_ASSERTION")
        val thread = pthread_self()!!
        threads[Worker.current] = thread
    }

    public fun dropWorker(worker: Worker) {
        threads.remove(worker)
    }

    public fun getAllStackTraces(): List {
        if (kotlin.native.Platform.osFamily == OsFamily.WINDOWS) return emptyList()

        val result = mutableListOf()
        val removed = mutableSetOf()
        for ((worker, thread) in threads.entries) {
            try {
                val name = worker.name
                val stack = collectStack(thread)
                result += WorkerStacktrace(name, stack)
            } catch (_: Throwable) {
                removed.add(worker)
            }
        }

        removed.forEach {
            threads.remove(it)
        }

        return result
    }

    public fun printAllStackTraces() {
        getAllStackTraces().forEach {
            println(it.worker)
            it.stacktrace.forEach {
                println("\tat $it")
            }
        }
    }

    public fun stopAllWorkers() {
        for (worker in threads.keys) {
            if (worker == Worker.current) continue
            worker.requestTermination(processScheduledJobs = false)
        }

        threads.clear()
        registerCurrentThread()
    }
}

@InternalAPI
public class WorkerStacktrace(
    public val worker: String,
    public val stacktrace: List
)

internal expect fun collectStack(thread: pthread_t): List

internal expect fun setSignalHandler()




© 2015 - 2024 Weber Informatics LLC | Privacy Policy