Skip to content

Commit 80929f4

Browse files
committed
PyAtomicBorrow
1 parent abd1daa commit 80929f4

1 file changed

Lines changed: 58 additions & 0 deletions

File tree

crates/vm/src/object/ext.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,64 @@ impl PyAtomicRef<Option<PyObject>> {
463463
}
464464
}
465465

466+
/// Atomic borrowed (non-ref-counted) optional reference to a Python object.
467+
/// Unlike `PyAtomicRef`, this does NOT own the reference.
468+
/// The pointed-to object must outlive this reference.
469+
pub struct PyAtomicBorrow {
470+
inner: PyAtomic<*mut u8>,
471+
}
472+
473+
// Safety: Access patterns ensure the pointed-to object outlives this reference.
474+
// The owner (generator/coroutine) clears this in its Drop impl before deallocation.
475+
unsafe impl Send for PyAtomicBorrow {}
476+
unsafe impl Sync for PyAtomicBorrow {}
477+
478+
impl PyAtomicBorrow {
479+
pub fn new() -> Self {
480+
Self {
481+
inner: Radium::new(null_mut()),
482+
}
483+
}
484+
485+
pub fn store(&self, obj: &PyObject) {
486+
let ptr = obj as *const PyObject as *mut u8;
487+
Radium::store(&self.inner, ptr, Ordering::Relaxed);
488+
}
489+
490+
pub fn load(&self) -> Option<&PyObject> {
491+
let ptr = Radium::load(&self.inner, Ordering::Relaxed);
492+
if ptr.is_null() {
493+
None
494+
} else {
495+
Some(unsafe { &*(ptr as *const PyObject) })
496+
}
497+
}
498+
499+
pub fn clear(&self) {
500+
Radium::store(&self.inner, null_mut(), Ordering::Relaxed);
501+
}
502+
503+
pub fn to_owned(&self) -> Option<PyObjectRef> {
504+
self.load().map(|obj| obj.to_owned())
505+
}
506+
}
507+
508+
impl Default for PyAtomicBorrow {
509+
fn default() -> Self {
510+
Self::new()
511+
}
512+
}
513+
514+
impl fmt::Debug for PyAtomicBorrow {
515+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
516+
write!(
517+
f,
518+
"PyAtomicBorrow({:?})",
519+
Radium::load(&self.inner, Ordering::Relaxed)
520+
)
521+
}
522+
}
523+
466524
pub trait AsObject
467525
where
468526
Self: Borrow<PyObject>,

0 commit comments

Comments
 (0)