From a7b0a712042dcc60baf88a48d1220633ed4a192f Mon Sep 17 00:00:00 2001 From: Chirantan Ekbote Date: Mon, 21 May 2018 14:30:49 -0700 Subject: [PATCH] virtio-queue: Add an iterator over a descriptor chain Add a way to iterate over all the descriptors in a descriptor chain. This is different from AvailIter, which iterates over all the descriptor chain heads in a queue. The new iterator struct provides readable() and writable() methods for iterating over just the readable or writable descriptors, respectively. BUG=chromium:703939 TEST=none Change-Id: Iea3fa5bb7662146a2d156a49ce8bb8ef00c522da Signed-off-by: Chirantan Ekbote Reviewed-on: https://chromium-review.googlesource.com/1065172 Reviewed-by: Zach Reizner Reviewed-by: Dylan Reid --- devices/src/virtio/queue.rs | 38 +++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/devices/src/virtio/queue.rs b/devices/src/virtio/queue.rs index 702c100f4c..7dab06c5f9 100644 --- a/devices/src/virtio/queue.rs +++ b/devices/src/virtio/queue.rs @@ -13,6 +13,37 @@ const VIRTQ_DESC_F_WRITE: u16 = 0x2; #[allow(dead_code)] const VIRTQ_DESC_F_INDIRECT: u16 = 0x4; +/// An iterator over a single descriptor chain. Not to be confused with AvailIter, +/// which iterates over the descriptor chain heads in a queue. +pub struct DescIter<'a> { + next: Option>, +} + +impl<'a> DescIter<'a> { + /// Returns an iterator that only yields the readable descriptors in the chain. + pub fn readable(self) -> impl Iterator> { + self.take_while(DescriptorChain::is_read_only) + } + + /// Returns an iterator that only yields the writable descriptors in the chain. + pub fn writable(self) -> impl Iterator> { + self.skip_while(DescriptorChain::is_read_only) + } +} + +impl<'a> Iterator for DescIter<'a> { + type Item = DescriptorChain<'a>; + + fn next(&mut self) -> Option { + if let Some(current) = self.next.take() { + self.next = current.next_descriptor(); + Some(current) + } else { + None + } + } +} + /// A virtio descriptor chain. #[derive(Clone)] pub struct DescriptorChain<'a> { @@ -126,6 +157,13 @@ impl<'a> DescriptorChain<'a> { None } } + + /// Produces an iterator over all the descriptors in this chain. + pub fn into_iter(self) -> DescIter<'a> { + DescIter { + next: Some(self), + } + } } /// Consuming iterator over all available descriptor chain heads in the queue.