Remove register_gil
This commit is contained in:
parent
7849b74dbf
commit
581e6e0924
|
@ -12,10 +12,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
|
||||
### Changed
|
||||
- Update `parking_lot` dependency to `0.11`. [#1010](https://github.com/PyO3/pyo3/pull/1010)
|
||||
- `PyString::to_string` is now renamed to `to_str` and returns `&str` instead of `Cow<str>`. [#1023](https://github.com/PyO3/pyo3/pull/1023)
|
||||
- `PyString::to_string` is now renamed `to_str` and returns `&str` instead of `Cow<str>`. [#1023](https://github.com/PyO3/pyo3/pull/1023)
|
||||
|
||||
### Removed
|
||||
- Remove `PyString::as_bytes` is removed. [#1023](https://github.com/PyO3/pyo3/pull/1023)
|
||||
- Remove `PyString::as_bytes`. [#1023](https://github.com/PyO3/pyo3/pull/1023)
|
||||
- Remove `Python::register_gil`. [#1023](https://github.com/PyO3/pyo3/pull/1023)
|
||||
|
||||
## [0.11.0] - 2020-06-28
|
||||
### Added
|
||||
|
|
68
src/gil.rs
68
src/gil.rs
|
@ -5,30 +5,10 @@
|
|||
use crate::{ffi, internal_tricks::Unsendable, Python};
|
||||
use parking_lot::{const_mutex, Mutex};
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::{any, mem::ManuallyDrop, ptr::NonNull, sync};
|
||||
use std::{mem::ManuallyDrop, ptr::NonNull, sync};
|
||||
|
||||
static START: sync::Once = sync::Once::new();
|
||||
|
||||
/// Holds temporally owned objects.
|
||||
struct ObjectHolder {
|
||||
/// Objects owned by the current thread
|
||||
obj: Vec<NonNull<ffi::PyObject>>,
|
||||
/// Non-python objects(e.g., String) owned by the current thread
|
||||
any: Vec<Box<dyn any::Any>>,
|
||||
}
|
||||
|
||||
impl ObjectHolder {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
obj: Vec::with_capacity(256),
|
||||
any: Vec::with_capacity(4),
|
||||
}
|
||||
}
|
||||
fn len(&self) -> (usize, usize) {
|
||||
(self.obj.len(), self.any.len())
|
||||
}
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
/// This is a internal counter in pyo3 monitoring whether this thread has the GIL.
|
||||
///
|
||||
|
@ -41,7 +21,7 @@ thread_local! {
|
|||
pub(crate) static GIL_COUNT: Cell<u32> = Cell::new(0);
|
||||
|
||||
/// Temporally hold objects that will be released when the GILPool drops.
|
||||
static OWNED_OBJECTS: RefCell<ObjectHolder> = RefCell::new(ObjectHolder::new());
|
||||
static OWNED_OBJECTS: RefCell<Vec<NonNull<ffi::PyObject>>> = RefCell::new(Vec::with_capacity(256));
|
||||
}
|
||||
|
||||
/// Check whether the GIL is acquired.
|
||||
|
@ -51,7 +31,7 @@ thread_local! {
|
|||
/// 2) PyGILState_Check always returns 1 if the sub-interpreter APIs have ever been called,
|
||||
/// which could lead to incorrect conclusions that the GIL is held.
|
||||
fn gil_is_acquired() -> bool {
|
||||
GIL_COUNT.with(|c| c.get() > 0)
|
||||
GIL_COUNT.try_with(|c| c.get() > 0).unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Prepares the use of Python in a free-threaded context.
|
||||
|
@ -159,13 +139,12 @@ impl GILGuard {
|
|||
pub fn acquire() -> GILGuard {
|
||||
prepare_freethreaded_python();
|
||||
|
||||
unsafe {
|
||||
let gstate = ffi::PyGILState_Ensure(); // acquire GIL
|
||||
let gstate = unsafe { ffi::PyGILState_Ensure() }; // acquire GIL
|
||||
|
||||
// If there's already a GILPool, we should not create another or this could lead to
|
||||
// incorrect dangling references in safe code (see #864).
|
||||
let pool = if !gil_is_acquired() {
|
||||
Some(GILPool::new())
|
||||
Some(unsafe { GILPool::new() })
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
@ -175,7 +154,6 @@ impl GILGuard {
|
|||
pool: ManuallyDrop::new(pool),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieves the marker type that proves that the GIL was acquired.
|
||||
#[inline]
|
||||
|
@ -252,7 +230,7 @@ static POOL: ReferencePool = ReferencePool::new();
|
|||
pub struct GILPool {
|
||||
/// Initial length of owned objects and anys.
|
||||
/// `Option` is used since TSL can be broken when `new` is called from `atexit`.
|
||||
start: Option<(usize, usize)>,
|
||||
start: Option<usize>,
|
||||
no_send: Unsendable,
|
||||
}
|
||||
|
||||
|
@ -283,20 +261,19 @@ impl GILPool {
|
|||
|
||||
impl Drop for GILPool {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
if let Some((obj_len_start, any_len_start)) = self.start {
|
||||
if let Some(obj_len_start) = self.start {
|
||||
let dropping_obj = OWNED_OBJECTS.with(|holder| {
|
||||
// `holder` must be dropped before calling Py_DECREF, or Py_DECREF may call
|
||||
// `GILPool::drop` recursively, resulting in invalid borrowing.
|
||||
let mut holder = holder.borrow_mut();
|
||||
holder.any.truncate(any_len_start);
|
||||
if obj_len_start < holder.obj.len() {
|
||||
holder.obj.split_off(obj_len_start)
|
||||
if obj_len_start < holder.len() {
|
||||
holder.split_off(obj_len_start)
|
||||
} else {
|
||||
Vec::new()
|
||||
}
|
||||
});
|
||||
for obj in dropping_obj {
|
||||
unsafe {
|
||||
ffi::Py_DECREF(obj.as_ptr());
|
||||
}
|
||||
}
|
||||
|
@ -343,36 +320,21 @@ pub unsafe fn register_decref(obj: NonNull<ffi::PyObject>) {
|
|||
/// The object must be an owned Python reference.
|
||||
pub unsafe fn register_owned(_py: Python, obj: NonNull<ffi::PyObject>) {
|
||||
debug_assert!(gil_is_acquired());
|
||||
// Ignoring the error means we do nothing if the TLS is broken.
|
||||
let _ = OWNED_OBJECTS.try_with(|holder| holder.borrow_mut().obj.push(obj));
|
||||
}
|
||||
|
||||
/// Register any value inside the GILPool.
|
||||
///
|
||||
/// # Safety
|
||||
/// It is the caller's responsibility to ensure that the inferred lifetime 'p is not inferred by
|
||||
/// the Rust compiler to outlast the current GILPool.
|
||||
pub unsafe fn register_any<'p, T: 'static>(obj: T) -> &'p T {
|
||||
debug_assert!(gil_is_acquired());
|
||||
OWNED_OBJECTS.with(|holder| {
|
||||
let boxed = Box::new(obj);
|
||||
let value_ref: *const T = &*boxed;
|
||||
holder.borrow_mut().any.push(boxed);
|
||||
&*value_ref
|
||||
})
|
||||
// Ignores the error in case this function called from `atexit`.
|
||||
let _ = OWNED_OBJECTS.try_with(|holder| holder.borrow_mut().push(obj));
|
||||
}
|
||||
|
||||
/// Increment pyo3's internal GIL count - to be called whenever GILPool or GILGuard is created.
|
||||
// Ignores the error in case this function called from `atexit`.
|
||||
#[inline(always)]
|
||||
fn increment_gil_count() {
|
||||
// Ignores the error in case this function called from `atexit`.
|
||||
let _ = GIL_COUNT.with(|c| c.set(c.get() + 1));
|
||||
}
|
||||
|
||||
/// Decrement pyo3's internal GIL count - to be called whenever GILPool or GILGuard is dropped.
|
||||
// Ignores the error in case this function called from `atexit`.
|
||||
#[inline(always)]
|
||||
fn decrement_gil_count() {
|
||||
// Ignores the error in case this function called from `atexit`.
|
||||
let _ = GIL_COUNT.try_with(|c| {
|
||||
let current = c.get();
|
||||
debug_assert!(
|
||||
|
@ -431,7 +393,7 @@ mod test {
|
|||
}
|
||||
|
||||
fn owned_object_count() -> usize {
|
||||
OWNED_OBJECTS.with(|holder| holder.borrow().obj.len())
|
||||
OWNED_OBJECTS.with(|holder| holder.borrow().len())
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -435,13 +435,6 @@ impl<'p> Python<'p> {
|
|||
FromPyPointer::from_borrowed_ptr_or_opt(self, ptr)
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
/// Passes value ownership to `Python` object and get reference back.
|
||||
/// Value get cleaned up on the GIL release.
|
||||
pub fn register_any<T: 'static>(self, ob: T) -> &'p T {
|
||||
unsafe { gil::register_any(ob) }
|
||||
}
|
||||
|
||||
/// Releases a PyObject reference.
|
||||
#[inline]
|
||||
pub fn release<T>(self, ob: T)
|
||||
|
|
Loading…
Reference in a new issue