Compiler says that data cannot be shared between threads safely even though the data is wrapped within a Mutex

社会主义新天地 提交于 2019-12-01 08:55:10

A Mutex is only Send or Sync if the value it contains is itself Send:

impl<T: ?Sized + Send> Send for Mutex<T>    
impl<T: ?Sized + Send> Sync for Mutex<T>

A &T is only Send when T is Sync:

impl<'a, T> Send for &'a T
where
    T: Sync + ?Sized, 

And a RefCell is never Sync

impl<T> !Sync for RefCell<T>
where
    T: ?Sized, 

As the error message states, your transaction contains a reference to a RefCell. It doesn't matter that there's a mutex, it's inherently not memory-safe to share it across threads. A simple reproduction:

use std::{cell::RefCell, sync::Mutex};

struct Connection(RefCell<i32>);
struct Transaction<'a>(&'a Connection);

fn is_send<T: Send>(_: T) {}

fn main() {
    let c = Connection(RefCell::new(42));
    let t = Transaction(&c);
    let m = Mutex::new(t);

    is_send(m);
}
error[E0277]: `std::cell::RefCell<i32>` cannot be shared between threads safely
  --> src/main.rs:13:5
   |
13 |     is_send(m);
   |     ^^^^^^^ `std::cell::RefCell<i32>` cannot be shared between threads safely
   |
   = help: within `Connection`, the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<i32>`
   = note: required because it appears within the type `Connection`
   = note: required because of the requirements on the impl of `std::marker::Send` for `&Connection`
   = note: required because it appears within the type `Transaction<'_>`
   = note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Mutex<Transaction<'_>>`
note: required by `is_send`
  --> src/main.rs:6:1
   |
6  | fn is_send<T: Send>(_: T) {}
   | ^^^^^^^^^^^^^^^^^^^^^^^^^

Why doesn't the compiler find RefCell to be safe anymore after being within a Connection referenced within a Transaction instead of solely within a Connection?

The RefCell is fine, it's the reference to a RefCell that is not.

Is the design of having the Connection and Transaction within the same struct a bad design [...] Do I need to redesign my data structures

Yes.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!