코딩Coding/Rust☑︎Release☀︎Notes_New◎Version

Rust 1.64 update 내용__Arc_drop 관련 업데이트 내용 분석중 ㅠㅠ

내인생PLUS 2022. 9. 24. 22:08
728x90

Decrement the reference counter, and drop and deallocate if it reaches zero.
Note: Even if this doesn’t yet decrement the counter to zero,
another thread might decrement it to zero and deallocate the data
before we exit this function, or even before fetch_sub()  returns,
invalidating our refcount reference. This is okay, though, because 
it’s a reference to an AtomicUsize.

 

참조 카운터를 줄이고 0에 도달하면 삭제 및 할당 해제하십시오.
참고: 이것이 아직 카운터를 0으로 감소시키지 않더라도,
다른 스레드는 그것을 0으로 줄이고 데이터 할당을 해제할 수 있다.
이 함수를 종료하기 전에 또는 fetch_sublic이 반환되기 전에
리카운트 참조가 무효화되었습니다. 그래도 괜찮아 왜냐면 
원자 사용에 대한 참조입니다.

 

 

 

https://twitter.com/m_ou_se/status/1572990699116859392/photo/1

 

트위터에서 즐기는 Mara Bos

“To allow for sound (unsafe) implementations of reference-counted allocated objects, it's no longer undefined behavior to keep a reference to something that's de-allocated, as long as you don't use it, and the object's bytes all reside in an UnsafeCell (

twitter.com

 

 

 

// https://stackoverflow.com/questions/64816028/how-can-i-determine-if-i-have-a-unique-arc-when-its-dropped

use std::sync::Arc;

#[derive(Debug)]
enum Action {
    One,
    Two,
    Three,
}

// Thing trait which operates on an Action, which should be a enum, allowing for
// different action sets.
trait Thing<T> {
    fn disconnected(&self);
    fn action(&self, action: T);
}

// There are many instances of an ActionController.
// There may be zero or more clones of an instance.
// The final drop of the instances should call thing.disconnected()
// In a multi-core environment, the same instance may be running on multiple cores
// ActionController should not be generic.
#[derive(Clone)]
struct ActionController {
    id: usize,
    thing: Arc<dyn Thing<Action>>,
}
impl ActionController {
    fn new(id: usize, thing: Box<dyn Thing<Action>>) -> Self {
        Self {
            id,
            thing: Arc::from(thing),
        }
    }
    fn invoke(&self, action: Action) {
        self.thing.action(action);
    }
}
// Decrement the reference counter, and drop and deallocate if it reaches zero.
// Note: Even if this doesn’t yet decrement the counter to zero,
// another thread might decrement it to zero and deallocate the data
// before we exit this function, or even before fetch_sub()  returns,
// invalidating our refcount reference. This is okay, though, because 
// it’s a reference to an AtomicUsize.

struct MyArc {}
impl Drop for MyArc<T> {
    fn drop(&mut self) {
        if refcount.fetch_sub(1, AcqRel) == 1 {
            unsafe {drop{Box::from_raw(ptr)}}
        }
    }
}
//
// To work around the drop issue, I've implemented Clone for ActionController which
// performs a fetch_add(1) on clone and a fetch_sub(1) on drop. This provides
// suficient information to call disconnected() -- but it just seems like there's
// got to be a better way.
impl Drop for ActionController {
    fn drop(&mut self) {
        // drop will be called for each clone of an Controller instance. When
        // the unique instance is dropped, disconnected() must be called
        self.thing.disconnected();
    }
}

struct Controlled {}
impl Thing<Action> for Controlled {
    fn disconnected(&self) {
        println!("disconnected")
    }
    fn action(&self, action: Action) {
        println!("action: {:#?}", action)
    }
}

fn bad() {
    let controlled = Controlled {};
    let controlled = Box::new(controlled) as Box<dyn Thing<Action>>;
    let controller = ActionController::new(1, controlled);
    let clone = controller.clone();
    controller.invoke(Action::One);
    clone.invoke(Action::Two);
    drop(controller);
    clone.invoke(Action::Three);
}

fn main() {
    bad();
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn incorrect() {
        bad();
    }
}

 

 

 

 

 

 

https://stackoverflow.com/questions/64816028/how-can-i-determine-if-i-have-a-unique-arc-when-its-dropped

 

How can I determine if I have a unique Arc when it's dropped?

I've an Arc<Mutex<Thing>> field in a struct which is cloned many times. It is shared between concurrent threads. Drop::drop is called for each clone as it goes out of scope. Is there an...

stackoverflow.com

 

 

 

 

 

 

반응형