Why it crash with this ```dispatch("Hello") { ...
# kotlin-native
k
Why it crash with this
Copy code
dispatch("Hello") {
        println("Printing $it from Thread Started \n")
    }
and not with this ?
Copy code
dispatch("Hello") {
        println(it)
        println("Printing from Thread Started \n")
    }
Code:
Copy code
fun <P, T> dispatch(param: P, block: (P) -> T) {
    val ref = StableRef.create(param to block)
    pthread_create(nativeHeap.alloc<pthread_tVar>().ptr, null, staticCFunction { data: COpaquePointer? ->
        data?.asStableRef<Pair<P, (P) -> T>>()?.get()?.let { it.second.invoke(it.first.freeze()) }
        NULL
    }.reinterpret(), ref.asCPointer())
    ref.dispose()
}
k
it's a timing issue. you're disposing the stable ref immediately after creating the thread
k
can you tell me how to dispose after pthread end ? cause without dispose it leak
k
dispose of it within the block you pass to the thread
k
I can't . staticCFunction can't take anything outside block
k
Also, if I understand correctly, neither
param
nor
block
are frozen.
block
is frozen at
it.first.freeze()
, but you’re already in another thread, which means you already have a race condition
k
you convert the pointer back to a stable ref in your block
k
@Kris Wong was that a reply to me or @Kavan?
k
@Kavan
k
Ah
k
This also crash if it's timing issue it should not
Copy code
fun <P, T> dispatch(param: P, block: (P) -> T) {
    val ref = StableRef.create(param to block)
    pthread_create(nativeHeap.alloc<pthread_tVar>().ptr, null, staticCFunction { data: COpaquePointer? ->
        data?.asStableRef<Pair<P, (P) -> T>>()?.get()?.let { it.second.invoke(it.first.freeze()) }
        NULL
    }.reinterpret(), ref.asCPointer())
    sleep(6)
    ref.dispose()
}
k
does it crash if you remove the dispose line?
k
Yup
k
So. StableRef does not make the data thread safe. You cannot pass mutable (unfrozen) state to another thread just by using StableRef
k
I tried freez() whole pair still crash
k
Sure, but you have multiple problems
k
hmm, ok. the docs are not clear on ownership when doing stable ref -> pointer -> stable ref. i suppose each ref is independent then.
k
The only thing stable ref does is add a +1 to the ref count. You cannot access the data from that pointer from a different thread if the data isn’t frozen. You can, however, pass the pointer between threads.
k
gotcha
k
Freeze the Pair, dispose inside the thread block. If there are still issues, work back from there and solve those.
k
I'm trying to pass variables and KFunction to C method. Can you re write code ?
@kpgalligan wait a sec let me try
You mean val pair = (param to block). freeze() and then pass it to StableRef.create(pair) ?
I tried it still crash
k
Define “still crash”. Does the error say the exact same thing every time?
k
Yahh non-zero exit value 139
I don't know how to get full crash log
k
You’ll need better debugging. I suggest logging out steps to find out exactly where it’s crashing
Copy code
println("a")
...
println("b")
k
I tried with --stacktrace
message has been deleted
k
That stack trace is java
Use print statements to isolate exactly what piece of code is crashing.
Unbundle this line into separate statements
data?.asStableRef<Pair<P, (P) -> T>>()?.get()?.let { it.second.invoke(it.first.freeze())
Use
println
between each so you can see where it actually crashes.
k
I checked everything works if I don't pass anything to it.first()
k
I don’t know what that means. It works if you leave first empty?
k
Yup
k
OK. So, if you don’t leave it empty, exactly what is crashing? You need to figure that out.
k
And also works if I pass anything but not use $it inside println
k
What println?
What is P, btw?
k
Copy code
dispatch("Hello") {
        println("Printing $it from Thread Started \n")
    }
I passed string so it's String
If I separate out it from println it prints
Without carsh
Like println(it); println("any text")
k
Post your whole code now. May help diagnose. However, if the param is a string, and you’re passing it correctly, and that’s actually crashing, I don’t know what to tell you
Try printing out the ‘first’ from the pair before you cross threads. Something is odd.
k
message has been deleted
If I println KFunction it crash
k
You kind of missed what I was going for here
Copy code
println("a")
it.second(it.first)
println("b")
More like that, but I guess it doesn’t matter
You should still remove the dispose at the end of the caller thread. Regardless of how everything plays out, you should dispose of that in the inner thread, or you need to wait on the caller thread (which defeats the purpose)
What’s with the uppercase NULL, btw?
k
Yahh cause staticCFunction return type is C so I'm passing null type of c otherwise it prints error c return type required
Fuck yahh it's fixed by adding initRuntimeIfNeeded()😳
message has been deleted
I looked in some kotlin native pre-made samples someone used this in staticCFunction block
k
Ah, yeah. That. I’m mostly in ios land and that gets called in interop
k
Well can you explain how it fixed, I'm bit new in threads
I'm much into Linux Kotlin Native. Love it. I think lots of native developers are in ios
Ohh you are guy who spoke in kotlinconf 2020 about worker and stuff ?
Cooool
I watched that presentation today morning.
I just seen your pic. I thought I seen somewhere that face. Then I see bio. You from touchlab. Then I got ohh that guy is from kotlinconf. Hahaha. I wanted to try pthreads and it's mutax to for learning. So looking lot materials on coroutines and threading in kotlin and found your worker presentation.
k
I am that guy. Not sure why
initRuntimeIfNeeded
fixes things, tbh. Would need to dig
k
Np. I will dig into.
k
Looks like it’s setting up a bunch of runtime memory stuff. I assume without that the internals crash: https://github.com/JetBrains/kotlin-native/blob/bcfd837363626f37cb906f5c77122019b00325bb/runtime/src/main/cpp/Runtime.cpp#L88
k
Hmm.. thanks for help.