Skip to content

Commit 6f02125

Browse files
authored
remove uneeded Pin from PyBuffer (#5417)
1 parent 0ee6eac commit 6f02125

File tree

1 file changed

+9
-20
lines changed

1 file changed

+9
-20
lines changed

src/buffer.rs

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,12 @@ use std::ffi::{
2525
c_ushort, c_void,
2626
};
2727
use std::marker::PhantomData;
28-
use std::pin::Pin;
29-
use std::{cell, mem, ptr, slice};
28+
use std::{cell, mem, slice};
3029
use std::{ffi::CStr, fmt::Debug};
3130

3231
/// Allows access to the underlying buffer used by a python object such as `bytes`, `bytearray` or `array.array`.
33-
// use Pin<Box> because Python expects that the Py_buffer struct has a stable memory address
3432
#[repr(transparent)]
35-
pub struct PyBuffer<T>(Pin<Box<ffi::Py_buffer>>, PhantomData<T>);
33+
pub struct PyBuffer<T>(Box<ffi::Py_buffer>, PhantomData<T>);
3634

3735
// PyBuffer is thread-safe: the shape of the buffer is immutable while a Py_buffer exists.
3836
// Accessing the buffer contents is protected using the GIL.
@@ -208,7 +206,7 @@ impl<T: Element> PyBuffer<T> {
208206
};
209207
// Create PyBuffer immediately so that if validation checks fail, the PyBuffer::drop code
210208
// will call PyBuffer_Release (thus avoiding any leaks).
211-
let buf = PyBuffer(Pin::from(buf), PhantomData);
209+
let buf = PyBuffer(buf, PhantomData);
212210

213211
if buf.0.shape.is_null() {
214212
Err(PyBufferError::new_err("shape is null"))
@@ -618,26 +616,17 @@ impl<T: Element> PyBuffer<T> {
618616
///
619617
/// This will automatically be called on drop.
620618
pub fn release(self, _py: Python<'_>) {
621-
// First move self into a ManuallyDrop, so that PyBuffer::drop will
622-
// never be called. (It would acquire the GIL and call PyBuffer_Release
623-
// again.)
624-
let mut mdself = mem::ManuallyDrop::new(self);
625-
unsafe {
626-
// Next, make the actual PyBuffer_Release call.
627-
ffi::PyBuffer_Release(&mut *mdself.0);
628-
629-
// Finally, drop the contained Pin<Box<_>> in place, to free the
630-
// Box memory.
631-
let inner: *mut Pin<Box<ffi::Py_buffer>> = &mut mdself.0;
632-
ptr::drop_in_place(inner);
633-
}
619+
// SAFETY: Self is `repr(transparent)` around a Box<ffi::Py_buffer>
620+
let mut inner: Box<ffi::Py_buffer> = unsafe { std::mem::transmute(self) };
621+
// SAFETY: the ffi::Py_buffer structure is valid until this release call
622+
unsafe { ffi::PyBuffer_Release(&mut *inner) };
634623
}
635624
}
636625

637626
impl<T> Drop for PyBuffer<T> {
638627
fn drop(&mut self) {
639-
fn inner(buf: &mut Pin<Box<ffi::Py_buffer>>) {
640-
if Python::try_attach(|_| unsafe { ffi::PyBuffer_Release(&mut **buf) }).is_none()
628+
fn inner(buf: &mut Box<ffi::Py_buffer>) {
629+
if Python::try_attach(|_| unsafe { ffi::PyBuffer_Release(buf.as_mut()) }).is_none()
641630
&& crate::internal::state::is_in_gc_traversal()
642631
{
643632
eprintln!("Warning: PyBuffer dropped while in GC traversal, this is a bug and will leak memory.");

0 commit comments

Comments
 (0)