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 <chirantan@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1065172
Reviewed-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
This commit is contained in:
Chirantan Ekbote 2018-05-21 14:30:49 -07:00 committed by chrome-bot
parent dd19b2e28a
commit a7b0a71204

View file

@ -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<DescriptorChain<'a>>,
}
impl<'a> DescIter<'a> {
/// Returns an iterator that only yields the readable descriptors in the chain.
pub fn readable(self) -> impl Iterator<Item=DescriptorChain<'a>> {
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<Item=DescriptorChain<'a>> {
self.skip_while(DescriptorChain::is_read_only)
}
}
impl<'a> Iterator for DescIter<'a> {
type Item = DescriptorChain<'a>;
fn next(&mut self) -> Option<Self::Item> {
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.