In kotlin/native, how would I create a frozen refe...
# kotlin-native
m
In kotlin/native, how would I create a frozen reference to a mutable object to read changes across threads? Basically, my front-end is a block editor similar to the Unreal Event Editor, and the back-end has a thread using the configuration from that editor in real-time. However, I can't use the MutableList of nodes I have since either it's not frozen and can't be shared, or it's frozen but then the front-end can't make any changes. I also considered stopping and restarting the backend thread, but since a frozen object can't be un-frozen, that's also not an option. I've tried doing some more hacky stuff with creating a COpaquePointer and pulling it from that, to avoid it from being frozen, but that still made the object exist in two threads and crash. I'd really like to know how to solve this, since I much prefer kotlin over C++ (where I did get this concept working).
k
We have multiple options for concurrent state here https://github.com/touchlab/Stately
☝️ 1
The short answer is atomics or thread-isolated state
👍 1
n
I recommend looking at the AtomicReference data type (works with reference based data types like String for example) from the Kotlin Standard library: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.native.concurrent/-atomic-reference/
Keep in mind when using the atomic data types the pitfalls, and performance overhead with using locks in a concurrent setting.
👍 1
k
If you're entirely in native, I'd agree. The only weird bit is you'll need to freeze your data explicitly. Maybe write your own 'val' extension that freezes it. There's also a form of atomic that acts like non-frozen state until it can't, but I'm on my phone right now, so can't really look it up...
On performance, definitely an issue. 3 years into kotlin native, I try really hard to keep things thread isolated, but it really depends what you're trying to do.
Also atomic ref has potential memory leaks...
a
With the atomic based approach the worst penalty is copying the list, which is O(N). With the thread-isolated state I believe the access time should be affected, as the list is used by a single dedicated thread, accessing threads are communicating to that thread. As far as I understand how it works, Kevin may correct me. If a queue would work for you, it is possible to create one with O(1) time complexity, yet "mutable" and shared between threads.
k
Thread isolated state does need to cross threads. The O time is what you'd normally expect for whatever the type is, but crossing threads can obviously impact performance. It works well with batched operations. Say you had a map. Adding 1000 entries is much faster if you pass them as a block rather than individually. It's easy to add methods. It's also simple to wrap any mutable type. It's kind of a weird structure, though, and I wouldn't say I use them a lot, but most of what we're doing is listening to the DB or calling the network. Not much need for concurrent collections