fn do_pop_unchecked<'a, 'b>(
        &'a mut self,
        mem: &'b GuestMemoryMmap,
    ) -> Option<DescriptorChain<'b>> {
        // This fence ensures all subsequent reads see the updated driver writes.
        fence(Ordering::Acquire);

        // We'll need to find the first available descriptor, that we haven't yet popped.
        // In a naive notation, that would be:
        // `descriptor_table[avail_ring[next_avail]]`.
        //
        // First, we compute the byte-offset (into `self.avail_ring`) of the index of the next available
        // descriptor. `self.avail_ring` stores the address of a `struct virtq_avail`, as defined by
        // the VirtIO spec:
        //
        // ```C
        // struct virtq_avail {
        //   le16 flags;
        //   le16 idx;
        //   le16 ring[QUEUE_SIZE];
        //   le16 used_event
        // }
        // ```
        //
        // We use `self.next_avail` to store the position, in `ring`, of the next available
        // descriptor index, with a twist: we always only increment `self.next_avail`, so the
        // actual position will be `self.next_avail % self.actual_size()`.
        // We are now looking for the offset of `ring[self.next_avail % self.actual_size()]`.
        // `ring` starts after `flags` and `idx` (4 bytes into `struct virtq_avail`), and holds
        // 2-byte items, so the offset will be:
        let index_offset = 4 + 2 * (self.next_avail.0 % self.actual_size());

        // `self.is_valid()` already performed all the bound checks on the descriptor table
        // and virtq rings, so it's safe to unwrap guest memory reads and to use unchecked
        // offsets.
        let desc_index: u16 = mem
            .read_obj(self.avail_ring.unchecked_add(u64::from(index_offset)))
            .unwrap();

        DescriptorChain::checked_new(mem, self.desc_table, self.actual_size(), desc_index).map(
            |dc| {
                self.next_avail += Wrapping(1);
                dc
            },
        )
    }
/// Pop the first available descriptor chain from the avail ring.
///
/// # Important
/// This is an internal method that ASSUMES THAT THERE ARE AVAILABLE DESCRIPTORS. Otherwise it
/// will retrieve a descriptor that contains garbage data (obsolete/empty).
Pop the first available descriptor chain from the avail ring.
Pop the first available descriptor chain from the avail ring .
fn do_pop_unchecked<'a, 'b>(
        &'a mut self,
        mem: &'b GuestMemoryMmap,
    ) -> Option<DescriptorChain<'b>> {
        // This fence ensures all subsequent reads see the updated driver writes.
        fence(Ordering::Acquire);
        // We'll need to find the first available descriptor, that we haven't yet popped.
        // In a naive notation, that would be:
        // `descriptor_table[avail_ring[next_avail]]`.
        //
        // First, we compute the byte-offset (into `self.avail_ring`) of the index of the next available
        // descriptor. `self.avail_ring` stores the address of a `struct virtq_avail`, as defined by
        // the VirtIO spec:
        //
        // ```C
        // struct virtq_avail {
        //   le16 flags;
        //   le16 idx;
        //   le16 ring[QUEUE_SIZE];
        //   le16 used_event
        // }
        // ```
        //
        // We use `self.next_avail` to store the position, in `ring`, of the next available
        // descriptor index, with a twist: we always only increment `self.next_avail`, so the
        // actual position will be `self.next_avail % self.actual_size()`.
        // We are now looking for the offset of `ring[self.next_avail % self.actual_size()]`.
        // `ring` starts after `flags` and `idx` (4 bytes into `struct virtq_avail`), and holds
        // 2-byte items, so the offset will be:
        let index_offset = 4 + 2 * (self.next_avail.0 % self.actual_size());
        // `self.is_valid()` already performed all the bound checks on the descriptor table
        // and virtq rings, so it's safe to unwrap guest memory reads and to use unchecked
        // offsets.
        let desc_index: u16 = mem
            .read_obj(self.avail_ring.unchecked_add(u64::from(index_offset)))
            .unwrap();
        DescriptorChain::checked_new(mem, self.desc_table, self.actual_size(), desc_index).map(
            |dc| {
                self.next_avail += Wrapping(1);
                dc
            },
        )
    }
fn do_pop_unchecked < ' a , ' b > ( & ' a mut self , mem : & ' b GuestMemoryMmap , ) -> Option < DescriptorChain < ' b > > { // This fence ensures all subsequent reads see the updated driver writes. fence ( Ordering :: Acquire ) ; // We'll need to find the first available descriptor, that we haven't yet popped. // In a naive notation, that would be: // `descriptor_table[avail_ring[next_avail]]`. // // First, we compute the byte-offset (into `self.avail_ring`) of the index of the next available // descriptor. `self.avail_ring` stores the address of a `struct virtq_avail`, as defined by // the VirtIO spec: // // ```C // struct virtq_avail { //   le16 flags; //   le16 idx; //   le16 ring[QUEUE_SIZE]; //   le16 used_event // } // ``` // // We use `self.next_avail` to store the position, in `ring`, of the next available // descriptor index, with a twist: we always only increment `self.next_avail`, so the // actual position will be `self.next_avail % self.actual_size()`. // We are now looking for the offset of `ring[self.next_avail % self.actual_size()]`. // `ring` starts after `flags` and `idx` (4 bytes into `struct virtq_avail`), and holds // 2-byte items, so the offset will be: let index_offset = 4 + 2 * ( self . next_avail . 0 % self . actual_size ( ) ) ; // `self.is_valid()` already performed all the bound checks on the descriptor table // and virtq rings, so it's safe to unwrap guest memory reads and to use unchecked // offsets. let desc_index : u16 = mem . read_obj ( self . avail_ring . unchecked_add ( u64 :: from ( index_offset ) ) ) . unwrap ( ) ; DescriptorChain :: checked_new ( mem , self . desc_table , self . actual_size ( ) , desc_index ) . map ( | dc | { self . next_avail += Wrapping ( 1 ) ; dc } , ) }
Pop the first available descriptor chain from the avail ring.
Pop the first available descriptor chain from the avail ring .
&'a mut self
mem
&'b GuestMemoryMmap
&'a mut self
mem
&'b GuestMemoryMmap
important
None