fix pointer release list
This commit is contained in:
parent
c1c4648add
commit
ce05cb91c0
|
@ -71,8 +71,6 @@ pub fn prepare_pyo3_library() {
|
|||
START_PYO3.call_once(|| unsafe {
|
||||
// initialize release pool
|
||||
POINTERS = Box::into_raw(Box::new(Pointers::new()));
|
||||
let p: &'static mut Pointers = mem::transmute(POINTERS);
|
||||
p.init();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -111,6 +109,7 @@ impl Drop for GILGuard {
|
|||
|
||||
|
||||
struct Pointers {
|
||||
rc: usize,
|
||||
owned: Vec<*mut ffi::PyObject>,
|
||||
borrowed: Vec<*mut ffi::PyObject>,
|
||||
pointers: *mut Vec<*mut ffi::PyObject>,
|
||||
|
@ -120,16 +119,13 @@ struct Pointers {
|
|||
impl Pointers {
|
||||
fn new() -> Pointers {
|
||||
Pointers {
|
||||
rc: 0,
|
||||
owned: Vec::with_capacity(250),
|
||||
borrowed: Vec::with_capacity(250),
|
||||
pointers: Box::into_raw(Box::new(Vec::with_capacity(250))),
|
||||
p: spin::Mutex::new(0 as *mut _),
|
||||
p: spin::Mutex::new(Box::into_raw(Box::new(Vec::with_capacity(250)))),
|
||||
}
|
||||
}
|
||||
fn init(&mut self) {
|
||||
let v = Box::into_raw(Box::new(Vec::with_capacity(250)));
|
||||
*self.p.lock() = v;
|
||||
}
|
||||
|
||||
unsafe fn release_pointers(&mut self) {
|
||||
let mut v = self.p.lock();
|
||||
|
@ -161,6 +157,8 @@ impl Pointers {
|
|||
}
|
||||
|
||||
self.release_pointers();
|
||||
|
||||
self.rc -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,9 +174,18 @@ impl Pool {
|
|||
#[inline]
|
||||
pub unsafe fn new() -> Pool {
|
||||
let p: &'static mut Pointers = mem::transmute(POINTERS);
|
||||
Pool{ owned: p.owned.len(),
|
||||
p.rc += 1;
|
||||
Pool {owned: p.owned.len(),
|
||||
borrowed: p.borrowed.len(),
|
||||
no_send: marker::PhantomData }
|
||||
no_send: marker::PhantomData}
|
||||
}
|
||||
pub unsafe fn new_if_needed() -> Option<Pool> {
|
||||
let p: &'static mut Pointers = mem::transmute(POINTERS);
|
||||
if p.rc == 0 {
|
||||
Some(Pool::new())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -226,6 +233,7 @@ impl GILGuard {
|
|||
unsafe {
|
||||
let gstate = ffi::PyGILState_Ensure(); // acquire GIL
|
||||
let pool: &'static mut Pointers = mem::transmute(POINTERS);
|
||||
pool.rc += 1;
|
||||
|
||||
GILGuard { owned: pool.owned.len(),
|
||||
borrowed: pool.borrowed.len(),
|
||||
|
|
|
@ -279,7 +279,7 @@ unsafe extern "C" fn tp_dealloc_callback<T>(obj: *mut ffi::PyObject)
|
|||
debug!("DEALLOC: {:?} - {:?}", obj,
|
||||
CStr::from_ptr((*(*obj).ob_type).tp_name).to_string_lossy());
|
||||
let guard = AbortOnDrop("Cannot unwind out of tp_dealloc");
|
||||
let _pool = pythonrun::Pool::new();
|
||||
let _pool = pythonrun::Pool::new_if_needed();
|
||||
let py = Python::assume_gil_acquired();
|
||||
let r = <T as PyObjectAlloc<T>>::dealloc(py, obj);
|
||||
mem::forget(guard);
|
||||
|
|
|
@ -62,13 +62,9 @@ fn class_with_docstr() {
|
|||
{
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
println!("TEST1");
|
||||
let typeobj = py.get_type::<ClassWithDocs>();
|
||||
println!("TEST2");
|
||||
py_run!(py, typeobj, "assert typeobj.__doc__ == 'Line1\\nLine2\\n Line3'");
|
||||
println!("TEST3");
|
||||
}
|
||||
println!("TEST4");
|
||||
}
|
||||
|
||||
#[py::class(name=CustomName)]
|
||||
|
@ -177,19 +173,27 @@ struct ClassWithFreelist{token: PyToken}
|
|||
|
||||
#[test]
|
||||
fn class_with_freelist() {
|
||||
let ptr;
|
||||
{
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let inst = Py::new(py, |t| ClassWithFreelist{token: t}).unwrap();
|
||||
let inst2 = Py::new(py, |t| ClassWithFreelist{token: t}).unwrap();
|
||||
let ptr = inst.as_ptr();
|
||||
ptr = inst.as_ptr();
|
||||
drop(inst);
|
||||
}
|
||||
|
||||
{
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let inst3 = Py::new(py, |t| ClassWithFreelist{token: t}).unwrap();
|
||||
assert_eq!(ptr, inst3.as_ptr());
|
||||
|
||||
let inst4 = Py::new(py, |t| ClassWithFreelist{token: t}).unwrap();
|
||||
assert_ne!(ptr, inst4.as_ptr())
|
||||
}
|
||||
}
|
||||
|
||||
struct TestDropCall {
|
||||
|
@ -210,11 +214,12 @@ struct DataIsDropped {
|
|||
|
||||
#[test]
|
||||
fn data_is_dropped() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let drop_called1 = Arc::new(AtomicBool::new(false));
|
||||
let drop_called2 = Arc::new(AtomicBool::new(false));
|
||||
|
||||
{
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let inst = py.init(|t| DataIsDropped{
|
||||
member1: TestDropCall { drop_called: drop_called1.clone() },
|
||||
member2: TestDropCall { drop_called: drop_called2.clone() },
|
||||
|
@ -223,6 +228,8 @@ fn data_is_dropped() {
|
|||
assert!(drop_called1.load(Ordering::Relaxed) == false);
|
||||
assert!(drop_called2.load(Ordering::Relaxed) == false);
|
||||
drop(inst);
|
||||
}
|
||||
|
||||
assert!(drop_called1.load(Ordering::Relaxed) == true);
|
||||
assert!(drop_called2.load(Ordering::Relaxed) == true);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue