Fix cell_lock, remove the RwLock<BufferOptions> from bytearray

This commit is contained in:
Noah committed 2020-11-08 15:01:46 -06:00
1 parent 17e0e75622
commit fce6e4c418
4 files changed
+51 -51

No files matched your search

+3 -3
View File
@@ -93,7 +93,7 @@ unsafe impl RawRwLock for RawCellRwLock {
#[inline]
fn lock_exclusive(&self) {
if !self.try_lock_exclusive() {
deadlock("exclusively", "RwLock")
deadlock("exclusively ", "RwLock")
}
self.state.set(WRITER_BIT)
}
@@ -126,7 +126,7 @@ unsafe impl RawRwLockDowngrade for RawCellRwLock {
unsafe impl RawRwLockUpgrade for RawCellRwLock {
#[inline]
fn lock_upgradable(&self) {
if self.try_lock_upgradable() {
if !self.try_lock_upgradable() {
deadlock("upgradably+sharedly ", "RwLock")
}
}
@@ -176,7 +176,7 @@ unsafe impl RawRwLockRecursive for RawCellRwLock {
#[inline]
fn lock_shared_recursive(&self) {
if !self.try_lock_shared_recursive() {
deadlock("recursively+sharedly", "RwLock")
deadlock("recursively+sharedly ", "RwLock")
}
}
+24 -26
View File
@@ -14,9 +14,7 @@ use crate::bytesinner::{
};
use crate::byteslike::PyBytesLike;
use crate::common::borrow::{BorrowedValue, BorrowedValueMut};
use crate::common::lock::{
PyRwLock, PyRwLockReadGuard, PyRwLockUpgradableReadGuard, PyRwLockWriteGuard,
};
use crate::common::lock::{PyRwLock, PyRwLockReadGuard, PyRwLockWriteGuard};
use crate::function::{OptionalArg, OptionalOption};
use crate::pyobject::{
BorrowValue, Either, IdProtocol, IntoPyObject, PyClassImpl, PyComparisonValue, PyContext,
@@ -45,7 +43,6 @@ use std::mem::size_of;
pub struct PyByteArray {
inner: PyRwLock<PyBytesInner>,
exports: AtomicCell<usize>,
buffer_options: PyRwLock<Option<Box<BufferOptions>>>,
}
pub type PyByteArrayRef = PyRef<PyByteArray>;
@@ -63,7 +60,6 @@ impl PyByteArray {
PyByteArray {
inner: PyRwLock::new(inner),
exports: AtomicCell::new(0),
buffer_options: PyRwLock::new(None),
}
}
@@ -667,40 +663,42 @@ impl Comparable for PyByteArray {
impl BufferProtocol for PyByteArray {
fn get_buffer(zelf: &PyRef<Self>, _vm: &VirtualMachine) -> PyResult<Box<dyn Buffer>> {
zelf.exports.fetch_add(1);
Ok(Box::new(zelf.clone()))
let buf = ByteArrayBuffer {
bytearray: zelf.clone(),
options: BufferOptions {
readonly: false,
len: zelf.len(),
..Default::default()
},
};
Ok(Box::new(buf))
}
}
impl Buffer for PyByteArrayRef {
#[derive(Debug)]
struct ByteArrayBuffer {
bytearray: PyByteArrayRef,
options: BufferOptions,
}
impl Buffer for ByteArrayBuffer {
fn obj_bytes(&self) -> BorrowedValue<[u8]> {
PyRwLockReadGuard::map(self.borrow_value(), |x| x.elements.as_slice()).into()
PyRwLockReadGuard::map(self.bytearray.borrow_value(), |x| x.elements.as_slice()).into()
}
fn obj_bytes_mut(&self) -> BorrowedValueMut<[u8]> {
PyRwLockWriteGuard::map(self.borrow_value_mut(), |x| x.elements.as_mut_slice()).into()
PyRwLockWriteGuard::map(self.bytearray.borrow_value_mut(), |x| {
x.elements.as_mut_slice()
})
.into()
}
fn release(&self) {
let mut w = self.buffer_options.write();
if self.exports.fetch_sub(1) == 1 {
*w = None;
}
self.bytearray.exports.fetch_sub(1);
}
fn get_options(&self) -> BorrowedValue<BufferOptions> {
let guard = self.buffer_options.upgradable_read();
let guard = if guard.is_none() {
let mut w = PyRwLockUpgradableReadGuard::upgrade(guard);
*w = Some(Box::new(BufferOptions {
readonly: false,
len: self.len(),
..Default::default()
}));
PyRwLockWriteGuard::downgrade(w)
} else {
PyRwLockUpgradableReadGuard::downgrade(guard)
};
PyRwLockReadGuard::map(guard, |x| x.as_ref().unwrap().as_ref()).into()
(&self.options).into()
}
}
+20 -20
View File
@@ -99,16 +99,14 @@ pub trait Buffer: Debug + PyThreadingConstraint {
fn release(&self);
fn as_contiguous(&self) -> Option<BorrowedValue<[u8]>> {
let options = self.get_options();
if !options.contiguous {
if !self.get_options().contiguous {
return None;
}
Some(self.obj_bytes())
}
fn as_contiguous_mut(&self) -> Option<BorrowedValueMut<[u8]>> {
let options = self.get_options();
if !options.contiguous {
if !self.get_options().contiguous {
return None;
}
Some(self.obj_bytes_mut())
@@ -513,16 +511,6 @@ impl PyMemoryView {
vm: &VirtualMachine,
) -> PyResult<()> {
let items = try_buffer_from_object(vm, &items)?;
let options = items.get_options();
let len = options.len;
let itemsize = options.itemsize;
if itemsize != zelf.options.itemsize {
return Err(vm.new_type_error(format!(
"memoryview: invalid type for format '{}'",
zelf.options.format
)));
}
let diff_err = || {
Err(vm.new_value_error(
@@ -530,8 +518,22 @@ impl PyMemoryView {
))
};
if options.format != zelf.options.format {
return diff_err();
let (len, itemsize);
{
let options = items.get_options();
len = options.len;
itemsize = options.itemsize;
if itemsize != zelf.options.itemsize {
return Err(vm.new_type_error(format!(
"memoryview: invalid type for format '{}'",
zelf.options.format
)));
}
if options.format != zelf.options.format {
return diff_err();
}
}
let (range, step, is_negative_step) = convert_slice(&slice, zelf.options.len, vm)?;
@@ -807,8 +809,7 @@ impl Buffer for PyMemoryViewRef {
}
fn as_contiguous(&self) -> Option<BorrowedValue<[u8]>> {
let options = self.get_options();
if !options.contiguous {
if !self.options.contiguous {
return None;
}
Some(BorrowedValue::map(self.obj_bytes(), |x| {
@@ -817,8 +818,7 @@ impl Buffer for PyMemoryViewRef {
}
fn as_contiguous_mut(&self) -> Option<BorrowedValueMut<[u8]>> {
let options = self.get_options();
if !options.contiguous {
if !self.options.contiguous {
return None;
}
Some(BorrowedValueMut::map(self.obj_bytes_mut(), |x| {
+4 -2
View File
@@ -97,11 +97,13 @@ pub fn try_rw_bytes_like<R>(
impl PyRwBytesLike {
pub fn new(vm: &VirtualMachine, obj: &PyObjectRef) -> PyResult<Self> {
let buffer = try_buffer_from_object(vm, &obj)?;
if !buffer.get_options().contiguous {
let options = buffer.get_options();
if !options.contiguous {
Err(vm.new_type_error("non-contiguous buffer is not a bytes-like object".to_owned()))
} else if buffer.get_options().readonly {
} else if options.readonly {
Err(vm.new_type_error("buffer is not a read-write bytes-like object".to_owned()))
} else {
drop(options);
Ok(Self(buffer))
}
}