openthread/ot/singleton/
backing.rs1use super::*;
6use std::cell::{Cell, RefCell};
7use std::task::Waker;
8
9#[allow(clippy::type_complexity)]
12pub(crate) struct InstanceBacking {
13 pub waker: Cell<Waker>,
14 pub platform: RefCell<std::boxed::Box<dyn Platform>>,
15 pub state_change_fn: Cell<Option<std::boxed::Box<dyn FnMut(ot::ChangedFlags)>>>,
16 pub cli_output_fn: Cell<Option<std::boxed::Box<dyn FnMut(&CStr)>>>,
17 pub ip6_receive_fn: Cell<Option<std::boxed::Box<dyn FnMut(OtMessageBox<'_>)>>>,
18 pub ip6_address_fn: Cell<Option<std::boxed::Box<dyn FnMut(Ip6AddressInfo<'_>, bool)>>>,
19 pub multicast_listener_callback:
20 Cell<Option<std::boxed::Box<dyn FnMut(BackboneRouterMulticastListenerEvent, &Ip6Address)>>>,
21 pub active_scan_fn: Cell<Option<std::boxed::Box<dyn FnMut(Option<&ActiveScanResult>)>>>,
22 pub energy_scan_fn: Cell<Option<std::boxed::Box<dyn FnMut(Option<&EnergyScanResult>)>>>,
23 pub joiner_fn: Cell<Option<std::boxed::Box<dyn FnOnce(Result)>>>,
24 pub srp_server_service_update_fn: Cell<
25 Option<std::boxed::Box<dyn FnMut(ot::SrpServerServiceUpdateId, &ot::SrpServerHost, u32)>>,
26 >,
27 pub dnssd_query_sub_unsub_fn: Cell<Option<std::boxed::Box<dyn FnMut(bool, &CStr)>>>,
28 pub nat64_receive_fn: Cell<Option<std::boxed::Box<dyn FnMut(OtMessageBox<'_>)>>>,
29 pub dhcp6pd_state_change_callback_fn:
30 Cell<Option<std::boxed::Box<dyn FnMut(BorderRoutingDhcp6PdState)>>>,
31 pub ephemeral_key_callback: Cell<Option<std::boxed::Box<dyn FnMut()>>>,
32 pub meshcop_service_changed_callback: Cell<Option<std::boxed::Box<dyn FnMut()>>>,
33}
34
35impl InstanceBacking {
36 pub(crate) fn new<T: Platform + 'static>(platform: T) -> Self {
37 Self {
38 waker: Cell::new(futures::task::noop_waker()),
39 platform: RefCell::new(Box::new(platform) as std::boxed::Box<dyn Platform>),
40 cli_output_fn: Cell::new(None),
41 ip6_receive_fn: Cell::new(None),
42 ip6_address_fn: Cell::new(None),
43 state_change_fn: Cell::new(None),
44 active_scan_fn: Cell::new(None),
45 energy_scan_fn: Cell::new(None),
46 joiner_fn: Cell::new(None),
47 srp_server_service_update_fn: Cell::new(None),
48 dnssd_query_sub_unsub_fn: Cell::new(None),
49 multicast_listener_callback: Cell::new(None),
50 nat64_receive_fn: Cell::new(None),
51 dhcp6pd_state_change_callback_fn: Cell::new(None),
52 ephemeral_key_callback: Cell::new(None),
53 meshcop_service_changed_callback: Cell::new(None),
54 }
55 }
56}
57
58impl InstanceBacking {
59 unsafe fn glob() -> &'static mut Option<InstanceBacking> {
60 static mut SINGLETON_BACKING: Option<InstanceBacking> = None;
61 #[allow(static_mut_refs)]
63 &mut SINGLETON_BACKING
64 }
65
66 pub(crate) unsafe fn as_ref() -> &'static InstanceBacking {
80 Self::glob().as_ref().expect("otInstance is uninitialized")
81 }
82
83 pub(crate) unsafe fn set_singleton(backing: InstanceBacking) {
96 trace!("Setting Singleton InstanceBacking");
97 assert!(Self::glob().replace(backing).is_none(), "Tried to make two OpenThread instances");
98 }
99
100 pub(crate) unsafe fn drop_singleton() {
112 trace!("Dropping Singleton InstanceBacking");
113 assert!(Self::glob().take().is_some(), "Tried to drop singleton that was never allocated");
114 }
115}