How Do I make a Type !Sync and/or !Send?

I have ( or plan to have, anyway ) a struct that represents a pointer to an FBO in OpenGL. The FBO cannot be shared across threads, and I want to make sure that Rust enforces this , by making my struct !Send and !Sync, but how do I do that. I tried this, but it is an unstable feature apparently:

struct Test;

impl !Sync for Test {}
impl !Send for Test {}

I mean, I could just include an Rc or something in the struct, but that seems kind of lame. I'm assuming there's a better way to do that.

1 Like

You can add a PhantomData<T> to your struct where T has the properties you want -- perhaps just a raw pointer will do.

1 Like

Hey, that worked nicely, thanks!

( playground )

use std::marker::PhantomData;

#[derive(Debug)]
struct Test {
    pointer: u32,
    /// This just makes this !Sync & !Send
    _phantom: PhantomData<*const usize>
}

impl Test {
    fn new() -> Self {
        Test {
            pointer: 0,
            _phantom: PhantomData
        }
    }
}

fn main() {
    let test = Test::new();
    let testref = &test;
    std::thread::spawn(|| {
        dbg!(test);
    });
    std::thread::spawn(|| {
        dbg!(testref);
    });
}

I think this is the first time I've ever tried to get a compiler error :wink: Rust is amazing. OpenGL is my first work with unsafe interfaces and this really shows the beauty in the way that Rust allows you to restrict usage of data and allows you to build abstractions on top of the unsafe world. :slight_smile:

1 Like