Type not Send/Sync even though wrapped in an Arc<Mutex<...>>. Why?

I have a type defined as follows:

#[derive(Clone)]
pub struct Filter(pub Arc<Mutex<dyn FnMut(&Path) -> bool>>);

When I attempt to use this in a threaded context the compiler complains that it is not "Send". Why would this not be "Send" and "Sync"?

Your dyn FnMut could be a closure that holds state which is not Send.

    let rc = Rc::new(0);
    let closure = move |_: &Path| { println!("{}", rc); true };
    let filter = Filter(Arc::new(Mutex::new(closure)));
    // The `Rc` is part of your compiler-derived closure struct
    // and thus the struct (closure) is not Send

You can prevent this by putting a bound on it:

pub struct Filter(pub Arc<Mutex<dyn FnMut(&Path) -> bool + Send>>);
1 Like

Thanks. I just figured it out before you responded, but thanks for the solution anyway.

More broadly, wrapping in Arc can never make anything Send or Sync that isn't already. Wrapping in Mutex or a similar type can add Sync, but only if Send is already present.

1 Like

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.