Implementing Send for a pointer wrapper

Viewed 251

I'm trying to understand exactly when I can have a type implement Send, and this isn't very clear from the Rust nomicon.

Specifically, I have a builder struct (say Builder) that contains a Vec<*mut std::os::raw::c_char>:

pub struct Builder{
    list: Vec<*mut std::os::raw::c_char>,
}

These pointers actually come from a destructured std::ffi::CString (by using std::ffi::CString::into_raw). Hence, these pointers are actually owned by the builder (in the sense that I manually implement Drop for Builder and reconstitute the std::ffi::CString to free the memory), but they have to be stored in this manner due to FFI requirements.

This builder type is not Copy and not Clone, so there will never be a situation where I end up with multiple builders thinking that they own the same char pointers. These pointers are also never exposed directly in the builder's public API.

Of course, since pointers are !Send and Vec of !Send is also !Send, Builder is !Send by default. However, it would appear to me, since my builder semantically maintains ownership of the pointers, that it is safe to manually implement Send for Builder. I believe what I'm doing is similar to manually implementing a Box, and Box is Send if the thing inside the box is also Send, just that in my case, the thing inside the "box" is logically a slice ([const std::os::raw::c_char], which is Send) instead of a raw pointer (*mut const std::os::raw::c_char, which is !Send).

Is this indeed the case (and is my understanding of Send correct), and is there anything else I should worry about when implementing Send for Builder?

0 Answers
Related