AtomicPtr vs Unique

I'm experimenting with a piece of open-source code you can see here that made use of the experimental std::ptr::Unique to share a reference across a few threads.

However, it appears Unique is gone in 1.28.0. so the app no longer compiles. Is AtomicPtr a good alternative (one challenge I've ran across already is it requires Sized)? ... Or is there a better solution?

Note: This application will only ever have 3 network connections and they are synchronized on the caller side already, so something like Tokio would probably be overkill. Yes... I'm a Rust newbie :slight_smile:

You already have a static reference to your app, why don't you just pass that to your threads?

Or, asking a different way: what's so special about your code that you need to resort to raw pointers instead of using the standard safe Rust primitives for shared resources?

1 Like

Unique was replaced with NonNull in Rust 1.25 and later. However, unlike Unique, NonNull does not implement Send and so it won't be useful for this purpose.

It looks like this code was mis-using Unique anyway, because it creates multiple "unique" pointers to the same value. Unique was only marked thread-safe because the creator was supposed to ensure that it was actually unique. Then each thread creates an &mut Application pointing to the same value, without any synchronization. This violates the aliasing rules and is undefined behavior.

A safe and correct way to do this would be to have TCPServer own an Arc<Mutex<A>> instead of an &A. Then it could give each thread a clone of the Arc, and the threads can synchronize their access to the Application.

2 Likes

The Arc<Mutex<>> is what I was just looking at. Thanks!

I agree I don't think raw pointers are necessary.

Passing the static around the threads are certainly possible, my concern with that is that if the behavior of the caller does change you could run into a potential race condition, correct?