Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect Send bounds on Ref #201

Closed
RustyYato opened this issue Apr 29, 2022 · 0 comments · Fixed by #202
Closed

Incorrect Send bounds on Ref #201

RustyYato opened this issue Apr 29, 2022 · 0 comments · Fixed by #202

Comments

@RustyYato
Copy link
Contributor

Currently it's possible to share unsynchronized types across thread boundaries. This is a major safety issue, and makes these types unsound.

NOTE: crossbeam is used for scoped threads only, we could use the stdlib's scoped threads on nightly, but this also works on stable :)

use dashmap::DashMap;
let map = DashMap::new();
let map = ↦

let count = 100;
let barrier = Arc::new(Barrier::new(count));

crossbeam::scope(move |s| {
    map.insert(0, (Cell::new(0), Cell::new(0)));

    for _ in 0..count {
        let value = map.get(&0).unwrap();
        s.spawn({
            let barrier = barrier.clone();
            move |_s| {
                barrier.wait();
                let (a, b) = &*value; // !!! We shouldn't be able to access this here!
                for _ in 0..100_000 {
                    a.set(a.get() + 1);
                    b.set(b.get() + 1);
                }
            }
        });
    }
})
.unwrap();
dbg!(map); // NOTE how the two cells are out of sync and not equal to `1_000_000`, which shows the data race in action

At a glance, here are the incorrect lines

  • unsafe impl<'a, K: Eq + Hash + Send, V: Send, S: BuildHasher> Send for RefMulti<'a, K, V, S> {}
  • unsafe impl<'a, K: Eq + Hash + Send, V: Send, S: BuildHasher> Send for Ref<'a, K, V, S> {}
  • unsafe impl<'a, K: Eq + Hash + Send, S: BuildHasher> Send for Ref<'a, K, S> {}

    Where ever you see K: Send or V: Send it should be K: Sync and V: Sync because your Ref types share access to the value. i.e. for the same reason that &T: Send if T: Sync.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant