Disclaimer: This question is very close to Passing two objects, where one holds a reference to another, into a thread, but not equal.
I have a C library which I call to get a pointer to a struct, and get a *mut ffi_context
back. I then wrap that pointer into a rust struct like this:
pub struct MyContext {
raw_context: *mut ffi_context
}
and implement a suitable Drop
method which frees the *mut ffi_context
.
Then I can use that context to obtain more structs (*mut ffi_context_dependant
), which must not outlive the context. I have consulted the nomicon, and added a PhantomData to my MyContextDependant struct, so rustc shouts at me if I violate the lifetime requirement:
pub struct MyContextDependant<'ctx> {
raw_context: *mut ffi_context_dependant,
_phantom: PhantomData<&'ctx MyContext>
}
Now I would like the types to be Send
-y. The C library states that one may use the structs from another thread, but not concurrently. That's good because this means I can implement Send
for those structs:
- I can pass &s to anyone (assuming the lifetimes hold) as long as there is no &mut (parallel reading causes no harm)
- I can pass a &mut to exactly one, if and only if no &s are being held
- I cannot move a dependant to a thread unless I prove the context lives long enough
However, it forbids me to to move the context and all dependants, which would (in reality) be totally safe as long as I enforce that the move's destination makes the context outlives all dependants.
Is there a sane way to express this in rust? Do I have to write (unsafe) helper functions which deconstruct my rust types, move the raw pointers, and reconstruct the rust types with the appropriate lifetimes?