D6631: rust-cpython: add macro for sharing references

kevincox (Kevin Cox) phabricator at mercurial-scm.org
Tue Jul 16 07:12:26 EDT 2019

kevincox added a comment.

  Is there any reason this can't be done using `Rc<RefCell<DirsMultiset>>`?  I have an example here: https://rust.godbolt.org/z/MNNR_F
  It uses `Rc` and `RefCell` however it does need to do some unsafe work to keep the RefCell borrowed for longer than would otherwise be easy to do. The advantages here are
  1. Lifetime is automatically managed by the Rc. This ensures that our parent data doesn't get deleted while the iterator is still alive.
  2. The linked implementation uses a mutable borrow. However it would be easy to make an immutable version which would allow multiple iterators over the same "container".
  3. Mutable access is managed by the RefCell so we don't need to do our own.


> macros.rs:45
> +///     data inner: RefCell<MyStruct>;
> +///     data leak_count: RefCell<usize>;
> +/// });

You aren't really using the `RefCell` type here. It might be better to just use `Cell` for the count and `UnsafeCell` for the data.

> macros.rs:57
> +    ) => {
> +        impl $name {
> +            fn leak_immutable(&self, py: Python) -> &'static $inner_struct {

Instead of adding methods to the interface type I would just create a templated struct which has these methods as well as the data and count. It doesn't seem like these actually need to be in the parent type.

> macros.rs:61
> +                *self.leak_count(py).borrow_mut() += 1;
> +                unsafe { &*ptr }
> +            }

I'm failing to see what actually prevents the "container" from being dropped while the "iterator" is alive. Is this somehow tied to the Python GC?

For example:

  c = RustObject()
  i = iter(i)
  del c
  # What is keeping the backing rust memory alive at this point.

  rHG Mercurial



To: Alphare, #hg-reviewers
Cc: durin42, kevincox, mercurial-devel

More information about the Mercurial-devel mailing list