1

So my current use case is I need to:

  1. Create a Vec<Box<Material>> where Material is a trait.
  2. Push boxed structs that impl Material into this Vec.
  3. Share a read only version of this vec to multiple threads.

My current approach is to use an Arc pointer for the Vec<..> and then clone it for each thread.

for example:

let mut materials: Vec<Box<Material>> = Vec::new();
// ... push stuff into materials
let materials = Arc::new(materials);
let mat_cloned = materials.clone();
// pool is a threadpool
pool.execute(move|| {
    // do read stuff with mat_cloned.
}

However I get the compiler error: dyn 'materials::Material' cannot be shared between threads safely

My understanding of it is that:

  1. Materials is a heap allocated vector of boxed pointers to various Material implementations.

  2. I then wrap with with an Arc type which is an atomically reference counted read-only pointer.

  3. I should be able to share this pointer with threads safely?

material::Material can't be shared safely but why not a Arc pointer to it?

NelsonGon
  • 13,015
  • 7
  • 27
  • 57
Tom Hadlaw
  • 123
  • 6

1 Answers1

1

If your Material trait is defined like:

trait Material{
...
}

Then, define it like:

trait Material: Send + Sync{
...
}

Here trait Material: Send + Sync means that every type that implements Material must also implement Send and Sync

material::Material can't be shared safely but why not a Arc pointer to it?

You have to let the compiler know that Box happens to hold something with the trait that happens to fulfill Send and Sync

OR

You can just change the declaration of materials to (For the same reason as above):

let mut materials: Vec<Box<Material + Send + Sync>> = Vec::new();
sn99
  • 843
  • 8
  • 24