I have a public variable: ```@SharedImmutable var ...
# kotlin-native
a
I have a public variable:
Copy code
@SharedImmutable
var APPENDER: Appender = ConsoleOutputAppender
And I have error
Copy code
kotlin.native.IncorrectDereferenceException: Trying to access top level value not marked as @ThreadLocal or @SharedImmutable from non-main thread
...
at 6  app.kexe           0x00000001022aae84 kfun:mu.<get-APPENDER>()Appender + 100 (File.kt:10:1)
on read this variable. But why?
@SharedImmutable
was added.
e
SharedImmutable
is applicable only to
val
, please, change
var
to
val
. Such code in
1.4
will produce error during compilation.
🎉 1
a
Thank you. But how can I set var (objects field) in main thread and read this in another one? Sync isn't needed
b
Nope, mutable state cannot be shared between threads
Non in a java-like way at least. To pass mutable state either copy it, freeze it and then pass it on or use AtomicFU
There's also object graph detachment and attachment, but that's a bit more advanced
OOOOR, add lax mode arg to compiler to shut him up and make KN threading work like java's, where everything goes
This article by mr @kpgalligan helped me a lot when I was bashing my head around it: https://medium.com/@kpgalligan/kotlin-native-stranger-threads-ep-1-1ccccdfe0c99
a
Just
AtomicReference
🙂
@kpgalligan, just read your new hands-on and while it's nice, it still doesn't touch the hot topic on how to pass mutable data between threads. Any chance you could write something up for that in the near future? I'm sure there are multiple ways to achieve that.
I remember this was THE only thing I couldn't find any info on when I was starting with K/N. All the articles talk about immutable-only state scenarios and issues with passing mutable state, but I couldn't find a single one that'd explain how to handle (o work around) mutable state. e.g. how do you implement a reducer store that works on its own dedicated thread, yet is able to expose current state snapshot to another thread
k
I intentionally don’t attempt to pass mutable state between threads. Ever. I wrote a post about how to do it, I skimming through I think I mostly talk about why you shouldn’t: https://dev.to/touchlab/kotlin-native-transferring-state-4n8i
“implement a reducer store that works on its own dedicated thread yet is able to expose current state snapshot to another thread”. Doing this would be tricky. If you needed the state to remain mutable, when you went to access it, you’d need a lock, then detach all of the state, attach to the caller thread, do a thing, then detach again. You can keep mutable state isolated to a thread and pass operations to it.
So, the caller thread would pass a lambda to the state container. That operation would be run in the state’s thread, but would have access to the mutable store. I would need to return a copy of whatever the called thread wanted, though (and that copy would be frozen).
I’m sort of overdue on content related to that
b
Do you plan on adding WASM target to stately libs? This is probably the only one that's missing
It's currently single-threaded, but in the near future they'll enable threads there as well. Yet it blocks me from using stately in my common sourceSet of my MPP project
k
Hadn’t thought about it much. I was under the impression wasm was getting a pretty big change and was not going to be a native target in the future, but I may completely misunderstand that.
b
True, but most of your libs there should only require declaring it in gradle so it'd be great to have it available now
Not to use it on wasm itself (as it's redundant) but to be able to use it in common modules for MPP that target wasm along with other native targets
k
Stately uses some native code for locks, among other things. I assume wasm would need an implementation (which, if single-threaded, would look a lot like JS). Just haven’t done that.
b
You could at least attach stately-isolate to this source-set https://github.com/touchlab/Stately/tree/master/stately-isolate/src/nativeCommonMain