Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::sync::{Arc, Mutex, Once};
- trait Doot {
- fn new(name: String) -> Self;
- }
- struct Birb {
- name: String,
- }
- impl Drop for Birb {
- fn drop(&mut self) {
- // This should happen
- println!("Dropping {}", self.name);
- }
- }
- struct CountedOption<T> {
- count: usize,
- value: Option<T>,
- }
- impl<T> CountedOption<T> {
- fn empty() -> Self {
- CountedOption {
- count: 0,
- value: None,
- }
- }
- }
- impl Doot for Birb {
- fn new(name: String) -> Self {
- Birb { name }
- }
- }
- lazy_static::lazy_static! {
- static ref BIRB_MUTEX: Arc<Mutex<CountedOption<Birb>>> = Arc::new(Mutex::new(CountedOption::empty()));
- }
- static INIT: Once = Once::new();
- struct BirbMutex {
- inner: Arc<Mutex<CountedOption<Birb>>>,
- }
- impl Doot for BirbMutex {
- fn new(name: String) -> Self {
- let mut co = BIRB_MUTEX
- .lock()
- .unwrap();
- if co.count == 0 {
- co
- .value
- .replace(Birb::new(name));
- }
- co.count += 1;
- BirbMutex {
- inner: BIRB_MUTEX.clone(),
- }
- }
- }
- impl Drop for BirbMutex {
- fn drop(&mut self) {
- let mut co = self.inner.lock().unwrap();
- co.count -= 1;
- println!("{}", co.count);
- if co.count == 0 {
- co.value = None;
- }
- }
- }
- fn foo() {
- let x1 = BirbMutex::new("George".to_string());
- let x2 = BirbMutex::new("Fred".to_string());
- }
- fn main() {
- foo();
- let x3 = BirbMutex::new("Hans".to_string());
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement