Visitar URL original
Hold atexit entries in PyRc rather than Arc · RustPython/RustPython@2a5aae5 · GitHub
Skip to content

Commit 2a5aae5

Browse files
committed
Hold atexit entries in PyRc rather than Arc
PyObjectRef is Send and Sync only under the threading feature, so an Arc over a callback entry trips clippy::arc_with_non_send_sync in builds without it, such as the wasm package. PyRc is Arc there and Rc otherwise. Assisted-by: Claude
1 parent ab1aaba commit 2a5aae5

2 files changed

Lines changed: 8 additions & 7 deletions

File tree

‎crates/vm/src/stdlib/atexit.rs‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,17 @@ pub(crate) use atexit::module_def;
33

44
#[pymodule]
55
mod atexit {
6-
use crate::{AsObject, PyObjectRef, PyResult, VirtualMachine, function::FuncArgs};
7-
use alloc::sync::Arc;
6+
use crate::{
7+
AsObject, PyObjectRef, PyResult, VirtualMachine, common::rc::PyRc, function::FuncArgs,
8+
};
89

910
#[pyfunction]
1011
fn register(func: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyObjectRef {
1112
// Callbacks go in LIFO order (insert at front)
1213
vm.state
1314
.atexit_funcs
1415
.lock()
15-
.insert(0, Arc::new((func.clone(), args)));
16+
.insert(0, PyRc::new((func.clone(), args)));
1617
func
1718
}
1819

@@ -49,7 +50,7 @@ mod atexit {
4950
let mut funcs = vm.state.atexit_funcs.lock();
5051
let mut j = (funcs.len() as isize - 1).min(i);
5152
while j >= 0 {
52-
if Arc::ptr_eq(funcs.get(j as usize).unwrap(), &entry) {
53+
if PyRc::ptr_eq(funcs.get(j as usize).unwrap(), &entry) {
5354
funcs.remove(j as usize);
5455
i = j;
5556
break;
@@ -73,7 +74,7 @@ mod atexit {
7374
let funcs: Vec<_> = core::mem::take(&mut *vm.state.atexit_funcs.lock());
7475
// Callbacks stored in LIFO order, iterate forward
7576
for entry in funcs {
76-
let (func, args) = Arc::try_unwrap(entry).unwrap_or_else(|e| (*e).clone());
77+
let (func, args) = PyRc::try_unwrap(entry).unwrap_or_else(|e| (*e).clone());
7778
if let Err(e) = func.call(args, vm) {
7879
let exit = e.fast_isinstance(vm.ctx.exceptions.system_exit);
7980
let msg = func

‎crates/vm/src/vm/mod.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ use crate::{
4343
stdlib,
4444
warn::WarningsState,
4545
};
46-
use alloc::{borrow::Cow, collections::BTreeMap, sync::Arc};
46+
use alloc::{borrow::Cow, collections::BTreeMap};
4747
#[cfg(all(not(unix), feature = "threading"))]
4848
use core::ptr::NonNull;
4949
#[cfg(feature = "threading")]
@@ -742,7 +742,7 @@ pub struct PyGlobalState {
742742
/// Registered `atexit` callbacks, newest first. Shared ownership so
743743
/// `atexit.unregister` can keep the entry it is comparing alive while the
744744
/// list is unlocked, and still recognize it afterwards by identity.
745-
pub atexit_funcs: PyMutex<Vec<Arc<(PyObjectRef, FuncArgs)>>>,
745+
pub atexit_funcs: PyMutex<Vec<PyRc<(PyObjectRef, FuncArgs)>>>,
746746
pub codec_registry: CodecsRegistry,
747747
pub finalizing: AtomicBool,
748748
pub warnings: WarningsState,

0 commit comments

Comments
 (0)