Sharing buffer between threads without locking


#1

I’m trying to share a buffer between a thread writing to it and another thread reading from it without locking.
Sharing this buffer using Arc<Mutex> and locking it before reading and writing works.
I’d like to use unsafe to read and write this buffer without locking. The data does not have to be consistent while reading.

I’ve tried replacing the mutex with an UnsafeCell:

let frame = Arc::new(UnsafeCell::new(vec![0 as u8;1920*1080*3]));
let thread_data = data.clone();
unsafe {
    let mut thread_data = thread_data.into_inner();
    thread::spawn(move || {
        loop {
            for x in 0..1920 {
                   for y in 0..1080 {
                       let offset = x * 3 + y * 1920 * 3;
                       thread_data[offset] = 1;
                       thread_data[offset + 1] = 1;
                       thread_data[offset + 2] = 1;
                   }
               }
            }
       });
}
unsafe {
    texture.update(None, &frame.into_inner(), 1920 * 3).unwrap();
}

This leads to these borrow checker errors:

error[E0507]: cannot move out of borrowed content
  --> src/main.rs:37:31
   |
37 |         let mut thread_data = thread_data.into_inner();
   |                               ^^^^^^^^^^^ cannot move out of borrowed content

error[E0507]: cannot move out of borrowed content
  --> src/main.rs:69:35
   |
69 |             texture.update(None, &frame.into_inner(), 1920 * 3).unwrap();
   |                                   ^^^^ cannot move out of borrowed content

How can i share my buffer without locking?


#2

into_inner() is about moving data out of an UnsafeCell, consuming the cell in the process. To access data concurrently from multiple threads, you’ll want to use get() instead.