1
Fork 0

Multiple improvements to RwLocks

- Split `sys_common::RWLock` between `StaticRWLock` and `MovableRWLock`
- Unbox `RwLock` on some platforms (Windows, Wasm and unsupported)
- Simplify `RwLock::into_inner`
This commit is contained in:
Benoît du Garreau 2021-04-29 09:53:19 +02:00
parent 41278062c8
commit ac470e9585
10 changed files with 112 additions and 134 deletions

View file

@ -3,9 +3,7 @@ mod tests;
use crate::cell::UnsafeCell;
use crate::fmt;
use crate::mem;
use crate::ops::{Deref, DerefMut};
use crate::ptr;
use crate::sync::{poison, LockResult, TryLockError, TryLockResult};
use crate::sys_common::rwlock as sys;
@ -66,7 +64,7 @@ use crate::sys_common::rwlock as sys;
/// [`Mutex`]: super::Mutex
#[stable(feature = "rust1", since = "1.0.0")]
pub struct RwLock<T: ?Sized> {
inner: Box<sys::RWLock>,
inner: sys::MovableRWLock,
poison: poison::Flag,
data: UnsafeCell<T>,
}
@ -130,7 +128,7 @@ impl<T> RwLock<T> {
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new(t: T) -> RwLock<T> {
RwLock {
inner: box sys::RWLock::new(),
inner: sys::MovableRWLock::new(),
poison: poison::Flag::new(),
data: UnsafeCell::new(t),
}
@ -376,24 +374,8 @@ impl<T: ?Sized> RwLock<T> {
where
T: Sized,
{
// We know statically that there are no outstanding references to
// `self` so there's no need to lock the inner lock.
//
// To get the inner value, we'd like to call `data.into_inner()`,
// but because `RwLock` impl-s `Drop`, we can't move out of it, so
// we'll have to destructure it manually instead.
unsafe {
// Like `let RwLock { inner, poison, data } = self`.
let (inner, poison, data) = {
let RwLock { ref inner, ref poison, ref data } = self;
(ptr::read(inner), ptr::read(poison), ptr::read(data))
};
mem::forget(self);
inner.destroy(); // Keep in sync with the `Drop` impl.
drop(inner);
poison::map_result(poison.borrow(), |_| data.into_inner())
}
let data = self.data.into_inner();
poison::map_result(self.poison.borrow(), |_| data)
}
/// Returns a mutable reference to the underlying data.
@ -424,14 +406,6 @@ impl<T: ?Sized> RwLock<T> {
}
}
#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<#[may_dangle] T: ?Sized> Drop for RwLock<T> {
fn drop(&mut self) {
// IMPORTANT: This code needs to be kept in sync with `RwLock::into_inner`.
unsafe { self.inner.destroy() }
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLock<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {