audio_device/runtime/
mod.rs1mod atomic_waker;
5use crate::Result;
6use std::cell::Cell;
7use std::future::Future;
8use std::ptr;
9
10thread_local! {
11 static RUNTIME: Cell<*const Runtime> = Cell::new(ptr::null());
12}
13
14cfg_events_driver! {
15 pub(crate) mod events;
16 #[doc(hidden)]
17 pub use self::events::EventsDriver;
18
19 pub(crate) fn with_events<F, T>(f: F) -> T where F: FnOnce(&EventsDriver) -> T {
20 RUNTIME.with(|rt| {
21 let rt = unsafe { rt.get().as_ref().expect("missing audio runtime") };
24 f(&rt.events)
25 })
26 }
27}
28
29cfg_poll_driver! {
30 pub(crate) mod poll;
31 #[doc(hidden)]
32 pub use self::poll::{PollDriver, AsyncPoll};
33
34 pub(crate) fn with_poll<F, T>(f: F) -> T where F: FnOnce(&PollDriver) -> T {
35 RUNTIME.with(|rt| {
36 let rt = unsafe { rt.get().as_ref().expect("missing audio runtime") };
39 f(&rt.poll)
40 })
41 }
42}
43
44pub struct Runtime {
61 #[cfg(feature = "events-driver")]
62 events: self::events::EventsDriver,
63 #[cfg(feature = "poll-driver")]
64 poll: self::poll::PollDriver,
65}
66
67impl Runtime {
68 pub fn new() -> Result<Self> {
70 Ok(Self {
71 #[cfg(feature = "events-driver")]
72 events: self::events::EventsDriver::new()?,
73 #[cfg(feature = "poll-driver")]
74 poll: self::poll::PollDriver::new()?,
75 })
76 }
77
78 pub fn enter(&self) -> RuntimeGuard<'_> {
81 let old = RUNTIME.with(|rt| rt.replace(self as *const _));
82
83 RuntimeGuard {
84 _runtime: self,
85 old,
86 }
87 }
88
89 pub async fn wrap<F>(&self, f: F) -> F::Output
101 where
102 F: Future,
103 {
104 use std::pin::Pin;
105 use std::task::{Context, Poll};
106
107 return GuardFuture(self, f).await;
108
109 struct GuardFuture<'a, F>(&'a Runtime, F);
110
111 impl<'a, F> Future for GuardFuture<'a, F>
112 where
113 F: Future,
114 {
115 type Output = F::Output;
116
117 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
118 let _guard = self.0.enter();
119 let future = unsafe { Pin::map_unchecked_mut(self, |this| &mut this.1) };
120 future.poll(cx)
121 }
122 }
123 }
124
125 pub fn join(self) {
127 #[cfg(feature = "events-driver")]
128 let _ = self.events.join();
129 #[cfg(feature = "poll-driver")]
130 let _ = self.poll.join();
131 }
132}
133
134pub struct RuntimeGuard<'a> {
138 _runtime: &'a Runtime,
140 old: *const Runtime,
141}
142
143impl Drop for RuntimeGuard<'_> {
144 fn drop(&mut self) {
145 RUNTIME.with(|rt| {
146 rt.set(self.old);
147 })
148 }
149}