polyhorn_ios/raw/
queue.rs1use dispatch::Queue;
2use std::mem::drop;
3use std::sync::{Arc, Mutex};
4
5pub struct QueueBound<T>
10where
11 T: 'static,
12{
13 queue: Queue,
14 inner: Arc<Mutex<Option<InnerQueueBound<T>>>>,
15}
16
17impl<T> QueueBound<T>
18where
19 T: 'static,
20{
21 pub fn new<F>(queue: Queue, initializer: F) -> QueueBound<T>
25 where
26 F: FnOnce() -> T + Send + 'static,
27 {
28 let inner = Arc::new(Mutex::new(None));
29
30 queue.exec_async({
31 let inner = inner.clone();
32
33 move || {
34 inner
35 .lock()
36 .unwrap()
37 .replace(InnerQueueBound(initializer()));
38 }
39 });
40
41 QueueBound { queue, inner }
42 }
43
44 pub unsafe fn adopt(queue: Queue, value: T) -> QueueBound<T> {
46 let inner = Arc::new(Mutex::new(Some(InnerQueueBound(value))));
47
48 QueueBound { queue, inner }
49 }
50
51 pub fn with<F>(&self, task: F)
54 where
55 F: FnOnce(&mut T) + Send + 'static,
56 {
57 let inner = self.inner.clone();
58
59 self.queue.exec_async(move || {
60 if let Some(value) = inner.lock().unwrap().as_mut() {
61 task(&mut value.0);
62 }
63 })
64 }
65
66 pub unsafe fn with_adopt<F, V>(&self, value: V, task: F)
70 where
71 V: 'static,
72 F: FnOnce(&mut T, V) + Send + 'static,
73 {
74 let wrap = InnerQueueBound(value);
75 let inner = self.inner.clone();
76
77 self.queue.exec_async(move || {
78 if let Some(value) = inner.lock().unwrap().as_mut() {
79 task(&mut value.0, wrap.0);
80 }
81 });
82 }
83}
84
85impl<T> Drop for QueueBound<T>
86where
87 T: 'static,
88{
89 fn drop(&mut self) {
90 if let Some(value) = self.inner.lock().unwrap().take() {
91 self.queue.exec_async(move || drop(value));
92 }
93 }
94}
95
96struct InnerQueueBound<T>(T);
97
98unsafe impl<T> Send for InnerQueueBound<T> {}