use super::{compare_exchange, RelaxStrategy, RwArcInner, Spin, UPGRADED, WRITER};
use crate::externs::{
ops::{Deref, DerefMut},
sync::{atomic::Ordering, Arc},
};
pub struct HyperWriteArc<T: ?Sized + Clone, R: RelaxStrategy = Spin> {
pub(super) inner: Arc<RwArcInner<T, R>>,
pub(super) data: T,
}
impl<T: ?Sized + Clone, R: RelaxStrategy> Drop for HyperWriteArc<T, R> {
fn drop(&mut self) {
loop {
match compare_exchange(
&self.inner.lock,
0,
WRITER,
Ordering::Acquire,
Ordering::Relaxed,
false,
) {
Ok(_) => break,
Err(_) => R::relax(),
}
}
unsafe {
*self.inner.data.get() = self.data.clone();
}
self.inner
.lock
.fetch_and(!(WRITER | UPGRADED), Ordering::Release);
}
}
impl<T: ?Sized + Clone, R: RelaxStrategy> Deref for HyperWriteArc<T, R> {
type Target = T;
fn deref(&self) -> &T {
&self.data
}
}
impl<T: ?Sized + Clone, R: RelaxStrategy> DerefMut for HyperWriteArc<T, R> {
fn deref_mut(&mut self) -> &mut T {
&mut self.data
}
}