use core::{
borrow::BorrowMut,
ops::{Deref, Try},
pin::Pin,
};
use funty::Unsigned;
use atomex::{
x_deps::funty,
Bitwise, TrAtomicData, TrCmpxchOrderings,
};
use abs_sync::{
cancellation::TrCancellationToken,
sync_lock,
sync_tasks::TrSyncTask,
};
use super::rwlock_::{Acquire, may_cancel_with_impl_};
#[derive(Debug)]
pub struct ReaderGuard<'a, 'g, T, D, B, O>(Pin<&'g mut Acquire<'a, T, D, B, O>>)
where
T: 'a + ?Sized,
D: TrAtomicData + Unsigned,
<D as TrAtomicData>::AtomicCell: Bitwise,
B: BorrowMut<<D as TrAtomicData>::AtomicCell>,
O: TrCmpxchOrderings;
impl<'a, 'g, T, D, B, O> ReaderGuard<'a, 'g, T, D, B, O>
where
T: 'a + ?Sized,
D: TrAtomicData + Unsigned,
<D as TrAtomicData>::AtomicCell: Bitwise,
B: BorrowMut<<D as TrAtomicData>::AtomicCell>,
O: TrCmpxchOrderings,
{
pub(super) fn new(acquire: Pin<&'g mut Acquire<'a, T, D, B, O>>) -> Self {
ReaderGuard(acquire)
}
}
impl<'a, T, D, B, O> Deref for ReaderGuard<'a, '_, T, D, B, O>
where
T: 'a + ?Sized,
D: TrAtomicData + Unsigned,
<D as TrAtomicData>::AtomicCell: Bitwise,
B: BorrowMut<<D as TrAtomicData>::AtomicCell>,
O: TrCmpxchOrderings,
{
type Target = T;
fn deref(&self) -> &Self::Target {
self.0.deref_impl()
}
}
impl<'a, 'g, T, D, B, O> sync_lock::TrReaderGuard<'a, 'g, T>
for ReaderGuard<'a, 'g, T, D, B, O>
where
T: 'a + ?Sized,
D: TrAtomicData + Unsigned,
<D as TrAtomicData>::AtomicCell: Bitwise,
B: BorrowMut<<D as TrAtomicData>::AtomicCell>,
O: TrCmpxchOrderings,
{
type Acquire = Acquire<'a, T, D, B, O>;
}
impl<'a, T, D, B, O> Drop for ReaderGuard<'a, '_, T, D, B, O>
where
T: 'a + ?Sized,
D: TrAtomicData + Unsigned,
<D as TrAtomicData>::AtomicCell: Bitwise,
B: BorrowMut<<D as TrAtomicData>::AtomicCell>,
O: TrCmpxchOrderings,
{
fn drop(&mut self) {
self.0.as_mut().drop_reader_guard()
}
}
pub struct ReadTask<'a, 'g, T, D, B, O>(Pin<&'g mut Acquire<'a, T, D, B, O>>)
where
T: ?Sized,
D: TrAtomicData + Unsigned,
<D as TrAtomicData>::AtomicCell: Bitwise,
B: BorrowMut<<D as TrAtomicData>::AtomicCell>,
O: TrCmpxchOrderings;
impl<'a, 'g, T, D, B, O> ReadTask<'a, 'g, T, D, B, O>
where
T: ?Sized,
D: TrAtomicData + Unsigned,
<D as TrAtomicData>::AtomicCell: Bitwise,
B: BorrowMut<<D as TrAtomicData>::AtomicCell>,
O: TrCmpxchOrderings,
{
pub(super) fn new(acquire: Pin<&'g mut Acquire<'a, T, D, B, O>>) -> Self {
ReadTask(acquire)
}
#[inline(always)]
pub fn may_cancel_with<C>(
self,
cancel: Pin<&mut C>,
) -> Option<ReaderGuard<'a, 'g, T, D, B, O>>
where
C: TrCancellationToken,
{
may_cancel_with_impl_(
self,
|t| t.0.as_mut(),
Acquire::try_read,
cancel,
)
}
#[inline(always)]
pub fn wait(self) -> <Self as TrSyncTask>::MayCancelOutput {
TrSyncTask::wait(self)
}
}
impl<'a, 'g, T, D, B, O> TrSyncTask for ReadTask<'a, 'g, T, D, B, O>
where
T: ?Sized,
D: TrAtomicData + Unsigned,
<D as TrAtomicData>::AtomicCell: Bitwise,
B: BorrowMut<<D as TrAtomicData>::AtomicCell>,
O: TrCmpxchOrderings,
{
type MayCancelOutput = ReaderGuard<'a, 'g, T, D, B, O>;
#[inline(always)]
fn may_cancel_with<C>(
self,
cancel: Pin<&mut C>,
) -> impl Try<Output = Self::MayCancelOutput>
where
C: TrCancellationToken,
{
ReadTask::may_cancel_with(self, cancel)
}
}