1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
use super::*;
use crate::object::*;
use alloc::sync::{Arc, Weak};
pub struct EventPair {
base: KObjectBase,
_counter: CountHelper,
peer: Weak<EventPair>,
}
impl_kobject!(EventPair
fn allowed_signals(&self) -> Signal {
Signal::USER_ALL | Signal::SIGNALED
}
fn peer(&self) -> ZxResult<Arc<dyn KernelObject>> {
let peer = self.peer.upgrade().ok_or(ZxError::PEER_CLOSED)?;
Ok(peer)
}
fn related_koid(&self) -> KoID {
self.peer.upgrade().map(|p| p.id()).unwrap_or(0)
}
);
define_count_helper!(EventPair);
impl EventPair {
#[allow(unsafe_code)]
pub fn create() -> (Arc<Self>, Arc<Self>) {
let mut event0 = Arc::new(EventPair {
base: KObjectBase::default(),
_counter: CountHelper::new(),
peer: Weak::default(),
});
let event1 = Arc::new(EventPair {
base: KObjectBase::default(),
_counter: CountHelper::new(),
peer: Arc::downgrade(&event0),
});
unsafe {
Arc::get_mut_unchecked(&mut event0).peer = Arc::downgrade(&event1);
}
(event0, event1)
}
pub fn peer(&self) -> ZxResult<Arc<Self>> {
self.peer.upgrade().ok_or(ZxError::PEER_CLOSED)
}
}
impl Drop for EventPair {
fn drop(&mut self) {
if let Some(peer) = self.peer.upgrade() {
peer.base.signal_set(Signal::PEER_CLOSED);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_allowed_signals() {
let (event0, event1) = EventPair::create();
assert!(Signal::verify_user_signal(
event0.allowed_signals(),
(Signal::USER_SIGNAL_5 | Signal::SIGNALED).bits().into()
)
.is_ok());
assert_eq!(event0.allowed_signals(), event1.allowed_signals());
event0.peer().unwrap();
}
#[test]
fn peer_closed() {
let (event0, event1) = EventPair::create();
assert!(Arc::ptr_eq(&event0.peer().unwrap(), &event1));
assert_eq!(event0.related_koid(), event1.id());
drop(event1);
assert_eq!(event0.signal(), Signal::PEER_CLOSED);
assert_eq!(event0.peer().err(), Some(ZxError::PEER_CLOSED));
assert_eq!(event0.related_koid(), 0);
}
}