mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-29 03:04:38 +08:00
Fix cell_lock, remove the RwLock<BufferOptions> from bytearray
This commit is contained in:
4 files changed
+51
-51
No files matched your search
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user