korlibs-archive / korio

Korio: Kotlin cORoutines I/O : Virtual File System + Async/Sync Streams + Async TCP Client/Server + WebSockets for Multiplatform Kotlin 1.3

Home Page:https://korlibs.soywiz.com/korio/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Posix calls block main thread.

Kesanov opened this issue · comments

commented

Performing a posix call from suspend function blocks the whole UI, until the call returns.
For example, the button in the following code will become unresponsive, once firefox is launched.

button(100.0, 100.0, 2.0, "Open Browser") {
  onClick { platform.posix.system("firefox") }
}

That's expected.
KorGE event loop is single threaded. So coroutines are executed in the same thread in order. That's like in JS.
If you want to execute blocking stuff in a separate thread, you have to use a different dispatcher that uses threads.
For example:

onClick { withContext(Dispatchers.IO) { platform.posix.system("firefox") } }

Also note that you can open urls in korge with:

gameWindow.browse(URL("https://myurl/"))
commented

However, kotlinx.coroutines.Dispatchers.IO is available only on JVM, isn't it.

The browse command is neat!

commented

Maybe the special kotlinx native-mt should be used.

I belive we should use open (linux/mac) and CreateProcessW (on windows)

That covers this case: korlibs/korge#590

If you cannot use a dispatcher, then you might want to use the worker API (what I'm using on KorIM and KorAU to offload reading/decoding from the main thread): https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.native.concurrent/-worker/

commented

Worker doesn't seem to fix that issue. The following code with still block the UI:

// run from button.onClick
Worker.start().execute(TransferMode.SAFE, {}, { while (true) platofrm.posix._sleep(10000) }).consume({})

You cannot use consume, since that blocks the thread executing it waiting for the result.

what you can do is to check if the future is completed in each frame.

val future = worker.start.execute
while (future.state != SCHEDULED) delay(1.milliseconds)
val result = future.result
commented

Makes sense.
Btw, how does korge for example copy 1GB+ files without blocking main thread, despite the fact that kotlinx is single threaded on native?