Home > Software design >  How can NonNull be made thread safe in Rust?
How can NonNull be made thread safe in Rust?

Time:12-01

I cannot send non null type between threads in rust. I need to call a method on a NonNull pointer for the Windows rust API.

I have tried Arc<Mutex< NonNull>> and Arc<Mutex<RefCell<Box< NonNull>>> but cannot find a way to get send and sync for NonNull.

I would like the thread to halt and await the mutex, so calling a method or even mutating the NonNull type shouldnt be a threading problem but even with runtime borrow checking I get the error: 'NonNull<c_void> cannot be sent between threads safely' and then a list of:

required because of the requirements on the impl of 'Send'

..etc.

I am about to try passing in the method as dyn but this should be possible right?

CodePudding user response:

You need to provide an unsafe implementation of Send to inform the compiler that you've taken into account the thread-safety of the objects behind the pointer (which you did, since you want to use a mutex for synchronization). For example:

// Wrapper around `NonNull<RawType>` that just implements `Send`
struct WrappedPointer(NonNull<RawType>);
unsafe impl Send for WrappedPointer {}

// Safe wrapper around `WrappedPointer` that gives access to the pointer
// only with the mutex locked.
struct SafeType {
    inner: Mutex<WrappedPointer>,
}

impl SafeType {
    fn some_method(&self) {
        let locked = self.inner.lock();
        // use ptr in `locked` to implement functionality, but don't return it
    }
}
  • Related