cyclic_sync/
cyclic_sync.rs1use std::sync::{Arc, Mutex};
2
3use generic_cursors::mutex::MutexGuardStack;
4
5#[derive(Debug, Clone)]
6pub struct CyclicDataStructure<T> {
7 data: T,
8 next: Option<Arc<Mutex<Self>>>,
9}
10
11impl<T> CyclicDataStructure<T> {
12 fn next(&mut self) -> Option<&Mutex<Self>> {
13 self.next.as_deref()
14 }
15 fn insert_next(&mut self, new_next: Arc<Mutex<Self>>) -> Option<Arc<Mutex<Self>>> {
16 self.next.replace(new_next)
17 }
18 fn take_next(&mut self) -> Option<Arc<Mutex<Self>>> {
19 self.next.take()
20 }
21}
22
23fn main() {
24 let cycle_root = Arc::new(Mutex::new(CyclicDataStructure {
25 data: 0_u32,
26 next: None,
27 }));
28 let mut current = cycle_root.clone();
29 for i in (1..128).rev() {
30 current = Arc::new(Mutex::new(CyclicDataStructure {
31 data: i,
32 next: Some(current),
33 }))
34 }
35 cycle_root.lock().unwrap().next = Some(current);
36
37 let mut stack = MutexGuardStack::new(&cycle_root).expect("not mutable borrowed yet");
40 println!("Stack currently at item with value: {}", stack.top().data);
41 loop {
42 if let Err(_borrow_error) = stack
43 .descend_with(CyclicDataStructure::next, false)
44 .expect("no node has no next")
45 {
46 println!("Found a cycle!");
47 break;
48 }
49 println!("Descended successfully!");
50 println!("Stack currently at item with value: {}", stack.top().data);
51 }
52 println!("Stack currently at item with value: {}", stack.top().data);
53 loop {
54 if let None = stack.ascend() {
55 println!("Reached the head of the linked list!");
56 break;
57 }
58 println!("Ascended successfully!");
59 println!("Stack currently at item with value: {}", stack.top().data);
60 }
61
62 println!("(Breaking the cycle to prevent miri from complaining about memory leaks)");
63 stack.top_mut().take_next();
64}