Opaque ffi type representation

Hi, I am wrapping a c library for a device and I am thinking how to model the opaque type on rust side. The device's documentation says:

On a single given connection, calling library functions is generally not thread-safe, i.e. they must be called from within one thread or the calls must be serialized/synchronized by the user.

For simplicity I started with

#[derive(Debug)]
pub struct DeviceHandle {
        _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
}

which makes it not send and not sync. But I guess the doc says, that the type in fact is send but not sync. Is this interpretation correct? How can I achieve this? Is turning all &self into &mut self for all methods enough?

Thanks

I would agree with your interpretation of the documentation. You could keep your type as it is and implement Send yourself. Then your type should be Send, but not Sync.

unsafe impl Send for DeviceHandle {}
1 Like

This would work, since &mut is exclusive access, but is overkill and might be inconvenient for the user. It is sufficient just to make sure that your type does not implement Sync, because Sync means “this can have &s pointing to it from multiple threads”, so if it is not Sync then you know its &self methods will be called only sequentially.

3 Likes