1use log::debug;
5use std::sync::OnceLock;
6use tokio::sync::watch::{self, Receiver, Sender};
7
8static TRACE_SINGLETON: OnceLock<TraceSingleton> = OnceLock::new();
11
12pub trait WatcherInterface {
13 fn recv(&mut self) -> impl std::future::Future<Output = ()> + Send;
14}
15pub struct Watcher {
17 receiver: Receiver<()>,
18}
19
20impl Watcher {
21 pub fn new(receiver: Receiver<()>) -> Watcher {
22 Watcher { receiver }
23 }
24
25 pub async fn recv(&mut self) {
27 match self.receiver.changed().await {
28 Ok(_) => {} Err(_) => panic!("Dropping the sender should never happen"),
30 }
31 }
32}
33pub fn subscribe() -> Watcher {
36 let receiver = TRACE_SINGLETON.get_or_init(|| TraceSingleton::new()).sender.subscribe();
37 Watcher::new(receiver)
38}
39
40struct TraceSingleton {
42 sender: Sender<()>,
45}
46
47extern "C" fn c_callback() {
48 TRACE_SINGLETON
49 .get()
50 .expect("Unexpected callback called before observer initialization")
51 .sender
52 .send(())
53 .ok(); }
55
56impl TraceSingleton {
57 fn new() -> TraceSingleton {
58 debug!("Register trace provider");
59 fuchsia_trace_provider::trace_provider_create_with_fdio();
60 debug!("Setup trace observer callback");
61 fuchsia_trace_observer::start_trace_observer(c_callback);
62 let (sender, _) = watch::channel(());
63 TraceSingleton { sender }
64 }
65}