use std::sync::{Arc, Weak, Mutex}; use std::ptr; use r9_macro::SharedFromSelfLock; use r9_macro_derive::SharedFromSelfLock; #[derive(Default)] #[derive(SharedFromSelfLock)] pub struct ListHeadLock { prev: Weak::>, next: Weak::>, data: Weak::>, _self_wp: Weak::>, } unsafe impl Send for ListHeadLock {} unsafe impl Sync for ListHeadLock {} impl ListHeadLock { fn new(data: Weak::>) -> Arc::> { let this = Arc::new(Mutex::new(Self{ prev: Default::default(), next: Default::default(), data: data, _self_wp: Default::default(), })); this.lock().unwrap()._self_wp = Arc::downgrade(&this); this.lock().unwrap().init(); return this; } pub fn new_head() -> Arc::> { return Self::new(Default::default()); } pub fn new_node(data: Weak::>) -> Arc::> { return Self::new(data); } fn init(&mut self) { self.prev = Arc::downgrade(&self.shared_from_self_lock()); self.next = Arc::downgrade(&self.shared_from_self_lock()); } pub fn data(&self) -> Weak::> { return self.data.clone(); } pub fn del_init(&mut self) { self.next.upgrade().unwrap().lock().unwrap()._self_wp = self.prev.clone(); self.prev.upgrade().unwrap().lock().unwrap().next = self.next.clone(); self.init(); } pub fn empty(&self) -> bool { return ptr::eq(self.next.as_ptr(),Arc::as_ptr(&self.shared_from_self_lock())); } pub fn add_tail(head: &Arc::>, pnew: &Arc::>) { let prev = &head.lock().unwrap().prev.clone(); let next = head; next.lock().unwrap().prev = Arc::downgrade(pnew); pnew.lock().unwrap().next = Arc::downgrade(&next); pnew.lock().unwrap().prev = prev.clone(); prev.upgrade().unwrap().lock().unwrap().next = Arc::downgrade(pnew); } pub fn first_entry(&self) -> Weak::> { if self.empty() { panic!(""); } return self.next.upgrade().unwrap().lock().unwrap().data(); } pub fn replace_init(head: &Arc::>, pnew: &Arc::>) { if head.lock().unwrap().empty() { return; } pnew.lock().unwrap().next = head.lock().unwrap().next.clone(); pnew.lock().unwrap().next.upgrade().unwrap().lock().unwrap().prev = Arc::downgrade(pnew); pnew.lock().unwrap().prev = head.lock().unwrap().prev.clone(); pnew.lock().unwrap().prev.upgrade().unwrap().lock().unwrap().next = Arc::downgrade(pnew); head.lock().unwrap().init(); } pub fn for_each(&self, cb: fn (&Weak::>) -> bool) { let mut pos = self.next.clone(); let self_weak = Arc::downgrade(&self.shared_from_self_lock()); while !Weak::ptr_eq(&pos, &self_weak) { if !cb(&pos.upgrade().unwrap().lock().unwrap().data()) { break; } pos = pos.upgrade().unwrap().lock().unwrap().next.clone(); } } }