do not modify ref counter for borrowed ptr

This commit is contained in:
Nikolay Kim 2017-06-24 12:57:18 -07:00
parent 3a2004eab2
commit 082db89aa6
3 changed files with 49 additions and 49 deletions

View file

@ -91,7 +91,7 @@ impl PyObject {
if ptr.is_null() { if ptr.is_null() {
Err(PyErr::fetch(py)) Err(PyErr::fetch(py))
} else { } else {
Ok(unsafe{PyObject::from_owned_ptr(py, ptr)}) Ok(unsafe{PyObject::from_borrowed_ptr(py, ptr)})
} }
} }
@ -104,7 +104,7 @@ impl PyObject {
if ptr.is_null() { if ptr.is_null() {
None None
} else { } else {
Some(unsafe{PyObject::from_owned_ptr(py, ptr)}) Some(unsafe{PyObject::from_borrowed_ptr(py, ptr)})
} }
} }

View file

@ -274,7 +274,7 @@ impl<'p> Python<'p> {
where T: PyDowncastFrom where T: PyDowncastFrom
{ {
unsafe { unsafe {
let p = pythonrun::register_owned(self, obj); let p = pythonrun::register_owned(self, obj.into_ptr());
<T as PyDowncastFrom>::downcast_from(p) <T as PyDowncastFrom>::downcast_from(p)
} }
} }
@ -283,7 +283,7 @@ impl<'p> Python<'p> {
pub unsafe fn cast_as<T>(self, obj: PyObject) -> &'p T pub unsafe fn cast_as<T>(self, obj: PyObject) -> &'p T
where T: PyDowncastFrom where T: PyDowncastFrom
{ {
let p = pythonrun::register_owned(self, obj); let p = pythonrun::register_owned(self, obj.into_ptr());
<T as PyDowncastFrom>::unchecked_downcast_from(p) <T as PyDowncastFrom>::unchecked_downcast_from(p)
} }
@ -292,9 +292,12 @@ impl<'p> Python<'p> {
pub unsafe fn cast_from_ptr<T>(self, ptr: *mut ffi::PyObject) -> &'p T pub unsafe fn cast_from_ptr<T>(self, ptr: *mut ffi::PyObject) -> &'p T
where T: PyDowncastFrom where T: PyDowncastFrom
{ {
let obj = PyObject::from_owned_ptr_or_panic(self, ptr); if ptr.is_null() {
let p = pythonrun::register_owned(self, obj); ::err::panic_after_error();
<T as PyDowncastFrom>::unchecked_downcast_from(p) } else {
let p = pythonrun::register_owned(self, ptr);
<T as PyDowncastFrom>::unchecked_downcast_from(p)
}
} }
/// Register `ffi::PyObject` pointer in release pool, /// Register `ffi::PyObject` pointer in release pool,
@ -302,20 +305,24 @@ impl<'p> Python<'p> {
pub unsafe fn mut_cast_from_ptr<T>(self, ptr: *mut ffi::PyObject) -> &'p mut T pub unsafe fn mut_cast_from_ptr<T>(self, ptr: *mut ffi::PyObject) -> &'p mut T
where T: PyDowncastFrom where T: PyDowncastFrom
{ {
let obj = PyObject::from_owned_ptr_or_panic(self, ptr); if ptr.is_null() {
let p = pythonrun::register_owned(self, obj); ::err::panic_after_error();
<T as PyDowncastFrom>::unchecked_mut_downcast_from(p) } else {
let p = pythonrun::register_owned(self, ptr);
<T as PyDowncastFrom>::unchecked_mut_downcast_from(p)
}
} }
/// Register owned `ffi::PyObject` pointer in release pool. /// Register owned `ffi::PyObject` pointer in release pool.
/// Returns `Err(PyErr)` if the pointer is `null`. /// Returns `Err(PyErr)` if the pointer is `null`.
/// do unchecked downcast to specific Python object. /// do unchecked downcast to specific Python object.
pub fn cast_from_ptr_or_err<T>(self, ptr: *mut ffi::PyObject) -> PyResult<&'p T> pub unsafe fn cast_from_ptr_or_err<T>(self, ptr: *mut ffi::PyObject) -> PyResult<&'p T>
where T: PyDowncastFrom where T: PyDowncastFrom
{ {
let obj = PyObject::from_owned_ptr_or_err(self, ptr)?; if ptr.is_null() {
unsafe { Err(PyErr::fetch(self))
let p = pythonrun::register_owned(self, obj); } else {
let p = pythonrun::register_owned(self, ptr);
Ok(<T as PyDowncastFrom>::unchecked_downcast_from(p)) Ok(<T as PyDowncastFrom>::unchecked_downcast_from(p))
} }
} }
@ -323,17 +330,14 @@ impl<'p> Python<'p> {
/// Register owned `ffi::PyObject` pointer in release pool. /// Register owned `ffi::PyObject` pointer in release pool.
/// Returns `None` if the pointer is `null`. /// Returns `None` if the pointer is `null`.
/// do unchecked downcast to specific Python object. /// do unchecked downcast to specific Python object.
pub fn cast_from_ptr_or_opt<T>(self, ptr: *mut ffi::PyObject) -> Option<&'p T> pub unsafe fn cast_from_ptr_or_opt<T>(self, ptr: *mut ffi::PyObject) -> Option<&'p T>
where T: PyDowncastFrom where T: PyDowncastFrom
{ {
if ptr.is_null() { if ptr.is_null() {
None None
} else { } else {
unsafe { let p = pythonrun::register_owned(self, ptr);
let obj = PyObject::from_owned_ptr(self, ptr); Some(<T as PyDowncastFrom>::unchecked_downcast_from(p))
let p = pythonrun::register_owned(self, obj);
Some(<T as PyDowncastFrom>::unchecked_downcast_from(p))
}
} }
} }
@ -343,8 +347,7 @@ impl<'p> Python<'p> {
pub unsafe fn cast_from_borrowed_ptr<T>(self, ptr: *mut ffi::PyObject) -> &'p T pub unsafe fn cast_from_borrowed_ptr<T>(self, ptr: *mut ffi::PyObject) -> &'p T
where T: PyDowncastFrom where T: PyDowncastFrom
{ {
let obj = PyObject::from_borrowed_ptr(self, ptr); let p = pythonrun::register_borrowed(self, ptr);
let p = pythonrun::register_borrowed(self, obj);
<T as PyDowncastFrom>::unchecked_downcast_from(p) <T as PyDowncastFrom>::unchecked_downcast_from(p)
} }
@ -355,9 +358,12 @@ impl<'p> Python<'p> {
-> PyResult<&'p T> -> PyResult<&'p T>
where T: PyDowncastFrom where T: PyDowncastFrom
{ {
let obj = PyObject::from_borrowed_ptr_or_err(self, ptr)?; if ptr.is_null() {
let p = pythonrun::register_borrowed(self, obj); Err(PyErr::fetch(self))
Ok(<T as PyDowncastFrom>::unchecked_downcast_from(p)) } else {
let p = pythonrun::register_borrowed(self, ptr);
Ok(<T as PyDowncastFrom>::unchecked_downcast_from(p))
}
} }
/// Register borrowed `ffi::PyObject` pointer in release pool. /// Register borrowed `ffi::PyObject` pointer in release pool.
@ -370,8 +376,7 @@ impl<'p> Python<'p> {
if ptr.is_null() { if ptr.is_null() {
None None
} else { } else {
let obj = PyObject::from_borrowed_ptr(self, ptr); let p = pythonrun::register_borrowed(self, ptr);
let p = pythonrun::register_borrowed(self, obj);
Some(<T as PyDowncastFrom>::unchecked_downcast_from(p)) Some(<T as PyDowncastFrom>::unchecked_downcast_from(p))
} }
} }
@ -382,14 +387,13 @@ impl<'p> Python<'p> {
pub unsafe fn mut_cast_from_borrowed_ptr<T>(self, ptr: *mut ffi::PyObject) -> &'p mut T pub unsafe fn mut_cast_from_borrowed_ptr<T>(self, ptr: *mut ffi::PyObject) -> &'p mut T
where T: PyDowncastFrom where T: PyDowncastFrom
{ {
let obj = PyObject::from_borrowed_ptr(self, ptr); let p = pythonrun::register_borrowed(self, ptr);
let p = pythonrun::register_borrowed(self, obj);
<T as PyDowncastFrom>::unchecked_mut_downcast_from(p) <T as PyDowncastFrom>::unchecked_mut_downcast_from(p)
} }
pub fn track_object(self, obj: PyObject) -> &'p PyObjectRef pub fn track_object(self, obj: PyObject) -> &'p PyObjectRef
{ {
unsafe { pythonrun::register_owned(self, obj) } unsafe { pythonrun::register_owned(self, obj.into_ptr()) }
} }
/// Release PyObject reference. /// Release PyObject reference.

View file

@ -4,8 +4,7 @@
use std::{sync, rc, marker, mem}; use std::{sync, rc, marker, mem};
use ffi; use ffi;
use python::{Python, ToPyPointer}; use python::Python;
use pointer::PyObject;
use objects::PyObjectRef; use objects::PyObjectRef;
static START: sync::Once = sync::ONCE_INIT; static START: sync::Once = sync::ONCE_INIT;
@ -106,8 +105,8 @@ impl Drop for GILGuard {
} }
} }
static mut OWNED: *mut Vec<PyObject> = 0 as *mut _; static mut OWNED: *mut Vec<*mut ffi::PyObject> = 0 as *mut _;
static mut BORROWED: *mut Vec<PyObject> = 0 as *mut _; static mut BORROWED: *mut Vec<*mut ffi::PyObject> = 0 as *mut _;
pub struct Pool { pub struct Pool {
owned: usize, owned: usize,
@ -118,8 +117,8 @@ pub struct Pool {
impl Pool { impl Pool {
#[inline] #[inline]
pub unsafe fn new() -> Pool { pub unsafe fn new() -> Pool {
let owned: &'static mut Vec<PyObject> = mem::transmute(OWNED); let owned: &'static mut Vec<*mut ffi::PyObject> = mem::transmute(OWNED);
let borrowed: &'static mut Vec<PyObject> = mem::transmute(BORROWED); let borrowed: &'static mut Vec<*mut ffi::PyObject> = mem::transmute(BORROWED);
Pool{ owned: owned.len(), Pool{ owned: owned.len(),
borrowed: borrowed.len(), borrowed: borrowed.len(),
no_send: marker::PhantomData } no_send: marker::PhantomData }
@ -139,35 +138,32 @@ impl Drop for Pool {
} }
} }
pub unsafe fn register_owned<'p>(_py: Python<'p>, obj: PyObject) -> &'p PyObjectRef { pub unsafe fn register_owned<'p>(_py: Python<'p>, obj: *mut ffi::PyObject) -> &'p PyObjectRef {
let pool: &'static mut Vec<PyObject> = mem::transmute(OWNED); let pool: &'static mut Vec<*mut ffi::PyObject> = mem::transmute(OWNED);
pool.push(obj); pool.push(obj);
mem::transmute(&pool[pool.len()-1]) mem::transmute(&pool[pool.len()-1])
} }
pub unsafe fn register_borrowed<'p>(_py: Python<'p>, obj: PyObject) -> &'p PyObjectRef { pub unsafe fn register_borrowed<'p>(_py: Python<'p>, obj: *mut ffi::PyObject) -> &'p PyObjectRef {
let pool: &'static mut Vec<PyObject> = mem::transmute(BORROWED); let pool: &'static mut Vec<*mut ffi::PyObject> = mem::transmute(BORROWED);
pool.push(obj); pool.push(obj);
mem::transmute(&pool[pool.len()-1]) mem::transmute(&pool[pool.len()-1])
} }
pub unsafe fn drain(owned: usize, borrowed: usize) { pub unsafe fn drain(owned: usize, borrowed: usize) {
let owned_pool: &'static mut Vec<PyObject> = mem::transmute(OWNED); let owned_pool: &'static mut Vec<*mut ffi::PyObject> = mem::transmute(OWNED);
let len = owned_pool.len(); let len = owned_pool.len();
if owned < len { if owned < len {
for ob in &mut owned_pool[owned..len] { for ptr in &mut owned_pool[owned..len] {
ffi::Py_DECREF(ob.as_ptr()); ffi::Py_DECREF(*ptr);
} }
owned_pool.set_len(owned); owned_pool.set_len(owned);
} }
let borrowed_pool: &'static mut Vec<PyObject> = mem::transmute(BORROWED); let borrowed_pool: &'static mut Vec<*mut ffi::PyObject> = mem::transmute(BORROWED);
let len = borrowed_pool.len(); let len = borrowed_pool.len();
if borrowed < len { if borrowed < len {
for ob in &mut borrowed_pool[borrowed..len] {
ffi::Py_DECREF(ob.as_ptr());
}
borrowed_pool.set_len(borrowed); borrowed_pool.set_len(borrowed);
} }
@ -184,8 +180,8 @@ impl GILGuard {
unsafe { unsafe {
let gstate = ffi::PyGILState_Ensure(); // acquire GIL let gstate = ffi::PyGILState_Ensure(); // acquire GIL
let owned: &'static mut Vec<PyObject> = mem::transmute(OWNED); let owned: &'static mut Vec<*mut ffi::PyObject> = mem::transmute(OWNED);
let borrowed: &'static mut Vec<PyObject> = mem::transmute(BORROWED); let borrowed: &'static mut Vec<*mut ffi::PyObject> = mem::transmute(BORROWED);
GILGuard { owned: owned.len(), GILGuard { owned: owned.len(),
borrowed: borrowed.len(), borrowed: borrowed.len(),