2

I created a Rust wrapper for a C++ library for a camera using bindgen, and the camera handle in the C++ library is defined as typedef void camera_handle which bindgen ported over as:

pub type camera_handle = ::std::os::raw::c_void;

I'm able to successfully connect to the camera and take images, however I wanted to run code on a separate thread for temperature control of the camera, essentially changing the cooler power based on the current temperature of the camera, which I want to have run separately from the rest of the code. These calls require the camera handle, but when I spawn a new thread, I keep getting the error:

'*mut std::ffi::c_void' cannot be sent between threads safely

And underneath it, it mentions:

the trait 'std::marker::Send' is not implemented for '*mut std::ffi::c_void'

How can I send this to another thread so I can use this camera handle there as well? I have tried using fragile and send_wrapper, but have been unsuccessful with both of them.

2
  • that have nothing to do with c_void you try to send the mutable pointer of something. That not allowed Commented Sep 22, 2021 at 23:56
  • @Stargateur Sending a mutable pointer is fine, it's a mutable reference that is forbidden from being shared - and converting a pointer to a reference requires an unsafe block. Rust additionally requires manually and unsafely implementing Send for pointers as precaution and a reminder to check that the pointers are used in accordance with Rust's rules. If the OP is only using the pointer for FFI, they should be safe (provided that the foreign API is itself thread safe). Commented Sep 23, 2021 at 8:53

1 Answer 1

7

Pointers do not implement Send or Sync since their safety escapes the compiler. You are intended to explicitly indicate when a pointer is safe to use across threads. This is typically done via a wrapper type that you implement Send and/or Sync on yourself:

struct CameraHandle(*mut c_void);

unsafe impl Send for CameraHandle {}
unsafe impl Sync for CameraHandle {}

Since implementing these traits manually is unsafe, you should be extra diligent to ensure that the types from the external library actually can be moved another thread (Send) and/or can be shared by multiple threads (Sync).

If you ever take advantage of the pointer's mutability without the protection of &mut self, it should probably not be Sync since having two &mut T at the same time is always unsound.

See:

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.