I'm using the downcast_rs crate to do downcast from Arc<Mutex<dyn MyTrait>>
to Arc<Mutex<MyConcreteObject>>
Normally when we have a non Sync
+ Send
type like MyStruct
, let's suppose here it's because it holds a pointer *mut u8
, we actually can think of Arc<Mutex<MyStruct>>
as being Sync
+ Send
, and do something like this:
struct SafeMyStruct(Arc<Mutex<MyStruct>>);
unsafe impl Send for SafeMyStruct {}
unsafe impl Sync for SafeMyStruct {}
so the compiler knows it's safe, because we'll only access those pointers one at a time because they are protected by a Mutex
.
Is this possible in downcast_rs
? Here's what I tried:
use downcast_rs::{DowncastSync, impl_downcast};
use std::sync::{Arc, Mutex};
trait Base: DowncastSync {}
impl_downcast!(sync Base);
#[derive(Debug)]
struct Foo {
x: *mut u8
}
//Make Arc<Mutex<Foo>>: Send + Sync
struct SafeFoo(Arc<Mutex<Foo>>);
unsafe impl Send for SafeFoo {}
unsafe impl Sync for SafeFoo {}
impl Base for Foo {}
fn main() {
let mut x = 0;
let base: Arc<Mutex<dyn Base>> = Arc::new(Mutex::new(Foo{x: &mut x}));
let base_ = base.clone();
std::thread::spawn(move ||{
base_;
});
}
Error:
error[E0277]: `*mut u8` cannot be shared between threads safely
--> src/main.rs:16:6
|
4 | trait Base: DowncastSync {}
| ------------ required by this bound in `Base`
...
16 | impl Base for Foo {}
| ^^^^ `*mut u8` cannot be shared between threads safely
|
= help: within `Foo`, the trait `Sync` is not implemented for `*mut u8`
= note: required because it appears within the type `Foo`
error[E0277]: `*mut u8` cannot be sent between threads safely
--> src/main.rs:16:6
|
4 | trait Base: DowncastSync {}
| ------------ required by this bound in `Base`
...
16 | impl Base for Foo {}
| ^^^^ `*mut u8` cannot be sent between threads safely
|
= help: within `Foo`, the trait `Send` is not implemented for `*mut u8`
= note: required because it appears within the type `Foo`
error: aborting due to 2 previous errors; 1 warning emitted
Even though Arc<Mutex<Foo>>
is Send + Sync
, it looks like it's forcing Foo
to be Send
+ Sync
, which would generate undefined behaviour if we implemented.
Is there a way to fix this?