Skip to content

Commit

Permalink
Merge pull request #899 from fusion-engineering-forks/mutex
Browse files Browse the repository at this point in the history
Simplify ReleasePool, remove parking_lot dependency.
  • Loading branch information
kngwyu committed May 5, 2020
2 parents c8fb8fc + 0407288 commit 626268d
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 35 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ inventory = "0.1.4"
libc = "0.2.62"
num-bigint = { version = "0.2", optional = true }
num-complex = { version = "0.2", optional = true }
parking_lot = { version = "0.10.2" }
paste = "0.1.6"
pyo3cls = { path = "pyo3cls", version = "=0.9.2" }
unindent = "0.1.4"
Expand Down
65 changes: 31 additions & 34 deletions src/gil.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
//! Interaction with python's global interpreter lock

use crate::{ffi, internal_tricks::Unsendable, Python};
use parking_lot::Mutex;
use std::cell::{Cell, RefCell, UnsafeCell};
use std::sync::atomic::{spin_loop_hint, AtomicBool, Ordering};
use std::{any, mem::ManuallyDrop, ptr::NonNull, sync};

static START: sync::Once = sync::Once::new();
Expand Down Expand Up @@ -153,54 +153,51 @@ impl Drop for GILGuard {

/// Thread-safe storage for objects which were dropped while the GIL was not held.
struct ReleasePool {
pointers_to_drop: Mutex<*mut Vec<NonNull<ffi::PyObject>>>,
pointers_being_dropped: UnsafeCell<*mut Vec<NonNull<ffi::PyObject>>>,
locked: AtomicBool,
pointers_to_drop: UnsafeCell<Vec<NonNull<ffi::PyObject>>>,
}

struct Lock<'a> {
lock: &'a AtomicBool,
}

impl<'a> Lock<'a> {
fn new(lock: &'a AtomicBool) -> Self {
while lock.compare_and_swap(false, true, Ordering::Acquire) {
spin_loop_hint();
}
Self { lock }
}
}

impl<'a> Drop for Lock<'a> {
fn drop(&mut self) {
self.lock.store(false, Ordering::Release);
}
}

impl ReleasePool {
const fn new() -> Self {
Self {
pointers_to_drop: parking_lot::const_mutex(std::ptr::null_mut()),
pointers_being_dropped: UnsafeCell::new(std::ptr::null_mut()),
locked: AtomicBool::new(false),
pointers_to_drop: UnsafeCell::new(Vec::new()),
}
}

fn register_pointer(&self, obj: NonNull<ffi::PyObject>) {
let mut storage = self.pointers_to_drop.lock();
if storage.is_null() {
*storage = Box::into_raw(Box::new(Vec::with_capacity(256)))
}
unsafe {
(**storage).push(obj);
}
let _lock = Lock::new(&self.locked);
let v = self.pointers_to_drop.get();
unsafe { (*v).push(obj) };
}

fn release_pointers(&self, _py: Python) {
let mut v = self.pointers_to_drop.lock();

if v.is_null() {
// No pointers have been registered
return;
}

let _lock = Lock::new(&self.locked);
let v = self.pointers_to_drop.get();
unsafe {
// Function is safe to call because GIL is held, so only one thread can be inside this
// block at a time

let vec = &mut **v;
if vec.is_empty() {
return;
}

// switch vectors
std::mem::swap(&mut *self.pointers_being_dropped.get(), &mut *v);
drop(v);

// release PyObjects
for ptr in vec.iter_mut() {
for ptr in &(*v) {
ffi::Py_DECREF(ptr.as_ptr());
}
vec.set_len(0);
(*v).clear();
}
}
}
Expand Down

0 comments on commit 626268d

Please sign in to comment.