runtime_capabilities/
handle.rs1use crate::CapabilityBound;
6use fidl::handle;
7use fuchsia_sync::Mutex;
8use std::sync::Arc;
9
10#[derive(Debug, Clone)]
12pub struct Handle(Arc<Mutex<Option<handle::NullableHandle>>>);
13
14impl Handle {
15 pub fn new(handle: handle::NullableHandle) -> Self {
17 Self(Arc::new(Mutex::new(Some(handle))))
18 }
19
20 pub fn duplicate(&self) -> Option<handle::NullableHandle> {
23 self.0.lock().as_ref().and_then(|h| h.duplicate_handle(handle::Rights::SAME_RIGHTS).ok())
24 }
25
26 pub fn take(&self) -> Option<handle::NullableHandle> {
28 self.0.lock().take()
29 }
30}
31
32impl CapabilityBound for Handle {
33 fn debug_typename() -> &'static str {
34 "Handle"
35 }
36}
37
38impl Handle {
39 pub fn try_clone(&self) -> Result<Self, ()> {
40 self.duplicate().map(Self::new).ok_or(())
41 }
42}
43
44#[cfg(target_os = "fuchsia")]
45#[cfg(test)]
46mod tests {
47 use super::*;
48 use crate::fidl::IntoFsandboxCapability;
49 use crate::{Capability, WeakInstanceToken};
50 use assert_matches::assert_matches;
51 use fidl_fuchsia_component_sandbox as fsandbox;
52
53 #[fuchsia::test]
55 async fn handle_into_fidl() {
56 let event = zx::Event::create();
57 let expected_koid = event.koid().unwrap();
58
59 let handle = Handle::new(event.into_handle());
60
61 let fidl_capability: fsandbox::Capability =
63 handle.into_fsandbox_capability(WeakInstanceToken::new_invalid());
64 assert_matches!(&fidl_capability, fsandbox::Capability::Handle(_));
65
66 let any: Capability = fidl_capability.try_into().unwrap();
67 let handle = assert_matches!(any, Capability::Handle(h) => h);
68
69 let handle: zx::NullableHandle = handle.take().unwrap();
71
72 let got_koid = handle.koid().unwrap();
74 assert_eq!(got_koid, expected_koid);
75 }
76
77 #[fuchsia::test]
79 async fn try_clone() {
80 let event = zx::Event::create();
81 let expected_koid = event.koid().unwrap();
82
83 let handle = Handle::new(event.into_handle());
84 let handle = handle.duplicate().unwrap();
85
86 let got_koid = handle.koid().unwrap();
87 assert_eq!(got_koid, expected_koid);
88
89 let (ch, _) = zx::Channel::create();
90 let handle = Handle::new(ch.into_handle());
91 assert_matches!(handle.try_clone(), Err(()));
92 }
93}