Why this struct is not Sync + Send?


As I protected the struct fields with a Mutex, shouldn't the struct S be Sync + Send?

Are you asking why get_s has to be adorned with Send and Sync?

fn get_s(l: Arc<dyn T>) -> Box<dyn L + Send + Sync>

the return type is like this in the proper code, it's Box<dyn Layer<S> + Send + Sync>
Layer being from tracing_subscriber

No, Mutex only gives you an additional Sync, and still requires Send (i. e. without Send you don't get the added Sync either).

However in this particular case, you’re not even putting an owned dyn T into the Mutex but an Arc, and Arc is only Send if the contained type is Sync + Send; the Mutex doesn’t really help at all (at least in therms of Send/Sync implementations)! The more common approach to combining Mutex and Arc is Arc<Mutex<…>> anyways, usually not Mutex<Arc<…>>.


God I feel stupid, I'm always mixing them in the wrong order, thanks!

1 Like

The way you can come to the correct conclusion about the order is to consider the sharing/ownership/uniqueness structure.

If you have a Mutex<Arc<T>>, then you will get exclusive access to the refcounted pointer. But that doesn't mean anything, because you can then freely clone that pointer and keep it around, even after the mutex is unlocked. Thus, the mutex didn't really prevent anyone from sharing the pointed value even in the absence of any mutices.

If you have an Arc<Mutex<T>>, then you will get shared access to the mutex, and you can clone the refcounted pointer, once again. However, the mutex now directly contains the value. When locked, it gives you a unique and exclusive MutexGuard, which you can use for mutating the inner value. Others with copies of the Arc pointing to the same Mutex<T> will not be able to mutate the wrapped value until you give up access to the lock.

Thus, you can see that the value must be uniquely owned by the mutex (which means direct containment here – other unique containers such as Box would also be fine) in order for the mutex to serve any purpose. This makes total sense: the whole point of a mutex is to turn shared access into unique access. It is thus futile to protect a shared ownership type such as Arc with a mutex.


Thank you very much, it makes much sense now!

I though I got it, but it seems I don't :frowning_face:

struct Mine {
    inner: Arc<Mutex<dyn SomeTrait>>,

Why Mine isn't Send + Sync?

Edit: because SomeTrain is not Send + Sync sorry for the noise ^^'

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.