Re: [TECH TOPIC] Rust for Linux

Wedson Almeida Filho
2021-07-08T14:24:41Z

On Thu, Jul 08, 2021 at 04:16:54PM +0200, Geert Uytterhoeven wrote:
> Hi Wedson,
>
> On Thu, Jul 8, 2021 at 3:54 PM Wedson Almeida Filho <wedsonaf@google.com> wrote:
> > On Thu, Jul 08, 2021 at 03:43:28PM +0200, Geert Uytterhoeven wrote:
> > > On Thu, Jul 8, 2021 at 3:42 PM Wedson Almeida Filho <wedsonaf@google.com> wrote:
> > > > On Thu, Jul 08, 2021 at 09:20:25AM +0200, Geert Uytterhoeven wrote:
> > > > > > Weak references need to upgraded to strong references before the underlying
> > > > > > objects can be accessed; upgrading may fail if the strong count has gone to
> > > > > > zero. It is, naturally, implemented as an increment that avoids going from 0 to
> > > > > > 1. It is safe to try to do it because the memory is kept alive while there are
> > > > > > weak references.
> > > > >
> > > > > What does "may fail" imply?
> > > >
> > > > Upgrading is essentially calling `refcount_inc_not_zero` on the strong count.
> > > > It succeeds when the count is already non-zero, it fails when the count is zero.
> > > >
> > > > So "may fail" here means "your attempt to upgrade came too late, the object is
> > > > gone". (The memory is still around so that attempts to upgrade don't cause UAF,
> > > > but the object is gone.)
> > >
> > > So what happens if this fails?
> >
> > You move on the next element in your data structure. This one doesn't really
> > exist anymore; once you release it lock, the cleanup code will likely come and
> > remove it.
>
> I'm confused. Which next element?

If you have a list of weak references, like in the original example, I'm
referring to the next element of the list. If this is just a field of some other
struct, then you're out of luck, you have to act as if the object didn't exist.

> What happens if I have a weak reference to an object that cannot be
> upgraded to a strong reference, and I try to access the object?
> E.g. read from or write to a member of the object?

You can't by construction. The returned type would be `Option<Ref<T>>`, so to
access the fields of the returned object, you need something like:

if let Some(obj) = weak.upgrade() {
// `obj` is accessible here, you can access the fields.
}

That is, if `upgrade` returns `None`, then you don't have a way to access the
fields of your struct. This is similar in concept to locks, where the fields of
a locked struct are only accessible when you acquire the lock.