-
Notifications
You must be signed in to change notification settings - Fork 455
/
Copy pathEnviroment.jvm.kt
63 lines (53 loc) · 1.84 KB
/
Enviroment.jvm.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package arrow.continuations
import java.util.concurrent.atomic.AtomicBoolean
import kotlin.coroutines.CoroutineContext
import kotlin.system.exitProcess
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.runBlocking
import sun.misc.Signal
import sun.misc.SignalHandler
public actual fun process(): Process = JvmProcess
public object JvmProcess : Process {
override fun onShutdown(block: suspend () -> Unit): suspend () -> Unit {
val isShutdown = AtomicBoolean(false)
fun shutdown() {
if (!isShutdown.getAndSet(true))
runBlocking {
// We don't call exit from ShutdownHook on JVM
try {
block()
} catch (e: Throwable) {
e.printStackTrace()
}
}
}
val hook = Thread(::shutdown, "Arrow-kt SuspendApp JVM ShutdownHook")
Runtime.getRuntime().addShutdownHook(hook)
return {
if (!isShutdown.get()) {
Runtime.getRuntime().removeShutdownHook(hook)
}
}
}
override fun onSigTerm(block: suspend (code: Int) -> Unit): Unit =
addSignalHandler("SIGTERM") { block(15) }
override fun onSigInt(block: suspend (code: Int) -> Unit): Unit =
addSignalHandler("SIGINT") { block(2) }
private fun addSignalHandler(signal: String, action: suspend () -> Unit): Unit =
try {
var handle: SignalHandler? = null
handle =
Signal.handle(Signal(signal)) { prev ->
runBlocking { action() }
if (handle != SignalHandler.SIG_DFL && handle != SignalHandler.SIG_IGN) {
handle?.handle(prev)
}
}
} catch (_: Throwable) {
/* Ignore */
}
override fun runScope(context: CoroutineContext, block: suspend CoroutineScope.() -> Unit): Unit =
runBlocking(context, block)
override fun exit(code: Int): Nothing = exitProcess(code)
override fun close(): Unit = Unit
}