How to use ffi, and transfer raw pointer

error[E0277]: `*mut std::ffi::c_void` cannot be sent between threads safely
   --> src/miner.rs:316:17
    |
316 |                 std::thread::spawn({
    |                 ^^^^^^^^^^^^^^^^^^ `*mut std::ffi::c_void` cannot be sent between threads safely
    |
    = help: within `cudalib::GpuContext`, the trait `std::marker::Send` is not implemented for `*mut std::ffi::c_void`
    = note: required because it appears within the type `cudalib::CudaStreamContext`
    = note: required because it appears within the type `cudalib::GpuContext`
    = note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Arc<cudalib::GpuContext>`
    = note: required because it appears within the type `[closure@src/cuda_worker.rs:17:5: 73:6 rx_read_replies:crossbeam_channel::channel::Receiver<reader::ReadReply>, benchmark:bool, tx_nonce_data:futures_channel::mpsc::Sender<miner::NonceData>, tx_empty_buffers:crossbeam_channel::channel::Sender<std::boxed::Box<(dyn miner::Buffer + std::marker::Send + 'static)>>, context_mu:std::sync::Arc<cudalib::GpuContext>]`
    = note: required because it appears within the type `impl std::ops::FnOnce<()>`

how to solve it?

We can't help much without further context. Raw pointers are not implements the Send trait so you can't send them between threads safely.

What's your problem? How's your current code trying to solve this problem, and if it doesn't work, what's the full error message the compiler says? What's your end goal by solving this problem? More we know, more we can help.

2 Likes

Rust assumes that all C code is not tread-safe, unless explicitly told otherwise.

When raw C pointers are wrapped in a struct (in this case CudaStreamContext), the crate that defines the struct has ability to say whether the C code that will use that pointer is thread-safe or not. Because cudalib has not specified that it is Send, then CudaStreamContext and GpuContext are not allowed to be moved between threads.

In short, cudalib forbids you from using threads. It may be an oversight (they forgot to add impl Send for CudaStreamContext, or it may be deliberate, because that context really is unsafe to use from another thread.

        println!("lanuch interval");
        let mut interval = time::interval(Duration::from_millis(get_mining_info_interval));
        println!("lanuch interval done");

run result

lanuch interval
thread 'main' panicked at 'there is no timer running, must be called from the context of Tokio runtime', /home/cery/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.21/src/time/driver/handle.rs:24:9

You've posted that answer in a wrong thread (Discourse is not thread-safe and allowed Send where it shouldn't have to)

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.