use crate::{
bindings,
fs::File,
prelude::*,
sync::{CondVar, LockClassKey},
};
use core::{marker::PhantomData, ops::Deref};
#[macro_export]
macro_rules! new_poll_condvar {
($($name:literal)?) => {
$crate::sync::poll::PollCondVar::new(
$crate::optional_name!($($name)?), $crate::static_lock_class!()
)
};
}
#[repr(transparent)]
pub struct PollTable<'a> {
table: *mut bindings::poll_table,
_lifetime: PhantomData<&'a bindings::poll_table>,
}
impl<'a> PollTable<'a> {
pub unsafe fn from_raw(table: *mut bindings::poll_table) -> Self {
PollTable {
table,
_lifetime: PhantomData,
}
}
pub fn register_wait(&self, file: &File, cv: &PollCondVar) {
unsafe { bindings::poll_wait(file.as_ptr(), cv.wait_queue_head.get(), self.table) }
}
}
#[pin_data(PinnedDrop)]
pub struct PollCondVar {
#[pin]
inner: CondVar,
}
impl PollCondVar {
pub fn new(name: &'static CStr, key: Pin<&'static LockClassKey>) -> impl PinInit<Self> {
pin_init!(Self {
inner <- CondVar::new(name, key),
})
}
}
impl Deref for PollCondVar {
type Target = CondVar;
fn deref(&self) -> &CondVar {
&self.inner
}
}
#[pinned_drop]
impl PinnedDrop for PollCondVar {
#[inline]
fn drop(self: Pin<&mut Self>) {
unsafe { bindings::__wake_up_pollfree(self.inner.wait_queue_head.get()) };
unsafe { bindings::synchronize_rcu() };
}
}