• Alice Ryhl's avatar
    rust: list: add ListArc · 6cd34171
    Alice Ryhl authored
    The `ListArc` type can be thought of as a special reference to a
    refcounted object that owns the permission to manipulate the
    `next`/`prev` pointers stored in the refcounted object. By ensuring that
    each object has only one `ListArc` reference, the owner of that
    reference is assured exclusive access to the `next`/`prev` pointers.
    When a `ListArc` is inserted into a `List`, the `List` takes ownership
    of the `ListArc` reference.
    
    There are various strategies for ensuring that a value has only one
    `ListArc` reference. The simplest is to convert a `UniqueArc` into a
    `ListArc`. However, the refcounted object could also keep track of
    whether a `ListArc` exists using a boolean, which could allow for the
    creation of new `ListArc` references from an `Arc` reference. Whatever
    strategy is used, the relevant tracking is referred to as "the tracking
    inside `T`", and the `ListArcSafe` trait (and its subtraits) are used to
    update the tracking when a `ListArc` is created or destroyed.
    
    Note that we allow the case where the tracking inside `T` thinks that a
    `ListArc` exists, but actually, there isn't a `ListArc`. However, we do
    not allow the opposite situation where a `ListArc` exists, but the
    tracking thinks it doesn't. This is because the former can at most
    result in us failing to create a `ListArc` when the operation could
    succeed, whereas the latter can result in the creation of two `ListArc`
    references. Only the latter situation can lead to memory safety issues.
    
    This patch introduces the `impl_list_arc_safe!` macro that allows you to
    implement `ListArcSafe` for types using the strategy where a `ListArc`
    can only be created from a `UniqueArc`. Other strategies are introduced
    in later patches.
    
    This is part of the linked list that Rust Binder will use for many
    different things. The strategy where a `ListArc` can only be created
    from a `UniqueArc` is actually sufficient for most of the objects that
    Rust Binder needs to insert into linked lists. Usually, these are todo
    items that are created and then immediately inserted into a queue.
    
    The const generic ID allows objects to have several prev/next pointer
    pairs so that the same object can be inserted into several different
    lists. You are able to have several `ListArc` references as long as they
    correspond to different pointer pairs. The ID itself is purely a
    compile-time concept and will not be present in the final binary. Both
    the `List` and the `ListArc` will need to agree on the ID for them to
    work together. Rust Binder uses this in a few places (e.g. death
    recipients) where the same object can be inserted into both generic todo
    lists and some other lists for tracking the status of the object.
    
    The ID is a const generic rather than a type parameter because the
    `pair_from_unique` method needs to be able to assert that the two ids
    are different. There's no easy way to assert that when using types
    instead of integers.
    Reviewed-by: default avatarBenno Lossin <benno.lossin@proton.me>
    Signed-off-by: default avatarAlice Ryhl <aliceryhl@google.com>
    Link: https://lore.kernel.org/r/20240814-linked-list-v5-2-f5f5e8075da0@google.comSigned-off-by: default avatarMiguel Ojeda <ojeda@kernel.org>
    6cd34171
list.rs 179 Bytes