@@ -25,14 +25,12 @@ use std::ffi::{
25
25
c_ushort, c_void,
26
26
} ;
27
27
use std:: marker:: PhantomData ;
28
- use std:: pin:: Pin ;
29
- use std:: { cell, mem, ptr, slice} ;
28
+ use std:: { cell, mem, slice} ;
30
29
use std:: { ffi:: CStr , fmt:: Debug } ;
31
30
32
31
/// 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
34
32
#[ 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 > ) ;
36
34
37
35
// PyBuffer is thread-safe: the shape of the buffer is immutable while a Py_buffer exists.
38
36
// Accessing the buffer contents is protected using the GIL.
@@ -208,7 +206,7 @@ impl<T: Element> PyBuffer<T> {
208
206
} ;
209
207
// Create PyBuffer immediately so that if validation checks fail, the PyBuffer::drop code
210
208
// will call PyBuffer_Release (thus avoiding any leaks).
211
- let buf = PyBuffer ( Pin :: from ( buf) , PhantomData ) ;
209
+ let buf = PyBuffer ( buf, PhantomData ) ;
212
210
213
211
if buf. 0 . shape . is_null ( ) {
214
212
Err ( PyBufferError :: new_err ( "shape is null" ) )
@@ -618,26 +616,17 @@ impl<T: Element> PyBuffer<T> {
618
616
///
619
617
/// This will automatically be called on drop.
620
618
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) } ;
634
623
}
635
624
}
636
625
637
626
impl < T > Drop for PyBuffer < T > {
638
627
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 ( )
641
630
&& crate :: internal:: state:: is_in_gc_traversal ( )
642
631
{
643
632
eprintln ! ( "Warning: PyBuffer dropped while in GC traversal, this is a bug and will leak memory." ) ;
0 commit comments