Coder Social home page Coder Social logo

atom's People

Contributors

bors[bot] avatar csherratt avatar dbkaplun avatar torkleyy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

atom's Issues

Feature: compare_and_swap/compare_exchange/compare_exchange_weak

Hello,

It would be great to have some more atomic methods available in Atom. I envision the following signatures, which attempt to maintain parity with AtomicPtr:

    // https://doc.rust-lang.org/std/sync/atomic/struct.AtomicPtr.html#method.compare_and_swap
    pub fn compare_and_swap(
        &self,
        current: Option<&P>,
        new: Option<P>,
        order: Ordering,
    ) -> Result<Option<P>, (Option<P>, *mut P)>;

    // https://doc.rust-lang.org/std/sync/atomic/struct.AtomicPtr.html#method.compare_exchange
    pub fn compare_exchange(
        &self,
        current: Option<&P>,
        new: Option<P>,
        success: Ordering,
        failure: Ordering,
    ) -> Result<Option<P>, (Option<P>, *mut P)>;

    // https://doc.rust-lang.org/std/sync/atomic/struct.AtomicPtr.html#method.compare_exchange_weak
    pub fn compare_exchange_weak(
        &self,
        current: Option<&P>,
        new: Option<P>,
        success: Ordering,
        failure: Ordering,
    ) -> Result<Option<P>, (Option<P>, *mut P)>;

Would you accept a PR for this?

Thanks for considering!

"This will try multiple times until it succeeds"

Is this accurate? It seems to simply rely on the atomic_xchg intrinsics, and not implement any kind of re-trying to block on the atom like the docstring suggests.

atom/src/lib.rs

Lines 64 to 66 in 2a606a0

/// Swap a new value into the Atom, This will try multiple
/// times until it succeeds. The old value will be returned.
pub fn swap(&self, v: P, order: Ordering) -> Option<P> {

AtomSetOnce incomplete documentation

The documentation for AtomSetOnce stops mid-sentence with Meaning that AtomSetOnce is not usable as a... . I would love to know how this sentence ends. The suspense is killing me! :D Seriously, though, what is AtomSetOnce not usable as? That would be pretty useful information to have.

Unsound: `Atom` accepts an unsafe memory ordering

This crate has the same issue as mystor/atomic_ref#5.

The following code segfaults on an AArch64 machine (but not on x86_64, which has a stronger memory model).

#![deny(unsafe_code)]
use atom::Atom;
use std::sync::atomic::Ordering;

fn main() {
    let channel = &*Box::leak(Box::new(Atom::<&&'static u32>::new(&&42u32)));

    std::thread::spawn(move || loop {
        if let Some(ptr) = channel.take(Ordering::Relaxed) {
            assert_eq!(**ptr, 42);
        }
    });

    for i in 0..10000000 {
        let b = Box::leak(Box::new(&42u32));
        channel.swap(b, Ordering::Relaxed);
    }
}

Create new cargo release to address safety issue

I noticed there's been a bunch of changes on master contributed by @dbkaplun that haven't made their way out onto the cargo crate. Most importantly, the latest release, 0.3.5 is missing dc096ef which fixes a fairly important soundness issue around the Send trait's bounds.

Without this commit, it's possible to Send across unsafe objects like Rc and potentially run into data races like so:

#![forbid(unsafe_code)]

extern crate atom;

use atom::Atom;
use std::rc::Rc;
use std::sync::mpsc;
use std::{thread, time, mem};

const NUM_CLONES: usize = 10000000;

fn main() {
    let x = Rc::new(());
    let y = Rc::clone(&x);

    // Place our Rc in the Atom through a Box.
    let shared_atom = Atom::empty();
    shared_atom.swap(Box::new(x));

    let child = thread::spawn(move || {
        // We now have the Rc shared across a thread.
        let x = shared_atom.take().unwrap();
        for _ in 0..NUM_CLONES {
            let clone = x.clone();
            mem::forget(clone);
        }
    });

    for _ in 0..NUM_CLONES {
        let clone = y.clone();
        mem::forget(clone);
    }

    // Wait for the spawned thread to finish its cloning.
    child.join().unwrap();

    // We made NUM_CLONES on both threads plus 2 references in the main thread.
    // But in reality we'll see that the strong_count varies across every run.
    assert_eq!(Rc::strong_count(&y), (NUM_CLONES * 2) + 2);
}

This could lead to use-after-frees and is a fairly easy mistake to make.

Unsound: `AtomSetOnce::dup` is not panic safe

#[test]
fn dup_panic_safety() {
    struct WeirdTy(String);

    impl Clone for WeirdTy {
        fn clone(&self) -> Self {
            panic!("")
        }
    }

    let x = AtomSetOnce::new(Box::new(WeirdTy("hoge".to_owned())));
    std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
        x.dup(Ordering::Acquire); // `v.clone()` panics, skipping `mem::forget(v)` and dropping `Box<WeirdTy>`
    }));
    // The `Box<WeirdTy>` is dropped again, causing a double-free
}

can not use Arc<dyn trait> with atom

Demo

trait Engine {
    fn eval(&self) -> String;
}

struct JSEngine {
    name: String,
}

impl Engine for JSEngine {
    fn eval(&self) -> String {
        "js eval".to_string()
    }
}

fn main() {
    let engine: Arc<dyn Engine> = Arc::new(JSEngine {
        name: "js1".to_string(),
    });
    println!("Results: {}", engine.eval());

    let shared_atom = Atom::new(engine);
}
error[E0277]: the size for values of type `dyn Engine` cannot be known at compilation time
  --> src/bin/main.rs:36:33
   |
36 |     let shared_atom = Atom::new(engine);
   |                                 ^^^^^^ doesn't have a size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `dyn Engine`
   = note: required because of the requirements on the impl of `atom::IntoRawPtr` for `std::sync::Arc<dyn Engine>`
   = note: required by `atom::Atom::<P>::new`

error[E0277]: the size for values of type `dyn Engine` cannot be known at compilation time
  --> src/bin/main.rs:36:23
   |
36 |     let shared_atom = Atom::new(engine);
   |                       ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
   | 
  :::~/.cargo/registry/src/github.com-1ecc6299db9ec823/atom-0.4.0/src/lib.rs:29:8
   |
29 |     P: IntoRawPtr + FromRawPtr,
   |        ---------- required by this bound in `atom::Atom`
   |
   = help: the trait `std::marker::Sized` is not implemented for `dyn Engine`
   = note: required because of the requirements on the impl of `atom::IntoRawPtr` for `std::sync::Arc<dyn Engine>`

error: aborting due to 2 previous errors; 2 warnings emitted

For more information about this error, try `rustc --explain E0277`.
error: could not compile `foo`.

To learn more, run the command again with --verbose.


Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.