Skip to content

Commit e987c81

Browse files
committed
queue: move go_to_previous_position() to AvailIter
The `AvailIter` structure is an iterator to consume all avialable descriptors on the available ring. And Queue::go_to_previous_position() is to go back one step on the available ring, or essentially undo the effect of AvailIter::next(). So let's move go_to_previous_position() to AvailIter. It helps to support multi-threading in future. Signed-off-by: Liu Jiang <gerry@linux.alibaba.com>
1 parent 0227728 commit e987c81

File tree

1 file changed

+23
-24
lines changed

1 file changed

+23
-24
lines changed

crates/virtio-queue/src/lib.rs

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,19 @@ pub struct AvailIter<'b, M: GuestAddressSpace> {
328328
next_avail: &'b mut Wrapping<u16>,
329329
}
330330

331+
impl<'b, M: GuestAddressSpace> AvailIter<'b, M> {
332+
/// Goes back one position in the available descriptor chain offered by the driver.
333+
///
334+
/// Rust does not support bidirectional iterators. This is the only way to revert the effect
335+
/// of an iterator increment on the queue.
336+
///
337+
/// Note: this method assumes there's only one thread manipulating the queue, so it should only
338+
/// be invoked in single-threaded context.
339+
pub fn go_to_previous_position(&mut self) {
340+
*self.next_avail -= Wrapping(1);
341+
}
342+
}
343+
331344
impl<'b, M: GuestAddressSpace> Iterator for AvailIter<'b, M> {
332345
type Item = DescriptorChain<M>;
333346

@@ -707,13 +720,6 @@ impl<M: GuestAddressSpace> QueueState<M> {
707720
Ok(true)
708721
}
709722

710-
/// Goes back one position in the available descriptor chain offered by the driver.
711-
/// Rust does not support bidirectional iterators. This is the only way to revert the effect
712-
/// of an iterator increment on the queue.
713-
pub fn go_to_previous_position(&mut self) {
714-
self.next_avail -= Wrapping(1);
715-
}
716-
717723
/// Returns the index for the next descriptor in the available ring.
718724
pub fn next_avail(&self) -> u16 {
719725
self.next_avail.0
@@ -804,13 +810,6 @@ impl<M: GuestAddressSpace> Queue<M> {
804810
self.state.needs_notification(&self.mem.memory())
805811
}
806812

807-
/// Goes back one position in the available descriptor chain offered by the driver.
808-
/// Rust does not support bidirectional iterators. This is the only way to revert the effect
809-
/// of an iterator increment on the queue.
810-
pub fn go_to_previous_position(&mut self) {
811-
self.state.go_to_previous_position()
812-
}
813-
814813
/// Returns the index for the next descriptor in the available ring.
815814
pub fn next_avail(&self) -> u16 {
816815
self.state.next_avail()
@@ -1082,17 +1081,17 @@ mod tests {
10821081
assert!(c.next().is_none());
10831082
assert_eq!(c.head_index(), 2);
10841083
}
1085-
}
10861084

1087-
// also test go_to_previous_position() works as expected
1088-
{
1089-
assert!(q.iter().unwrap().next().is_none());
1090-
q.go_to_previous_position();
1091-
let mut c = q.iter().unwrap().next().unwrap();
1092-
c.next().unwrap();
1093-
c.next().unwrap();
1094-
c.next().unwrap();
1095-
assert!(c.next().is_none());
1085+
// also test go_to_previous_position() works as expected
1086+
{
1087+
assert!(i.next().is_none());
1088+
i.go_to_previous_position();
1089+
let mut c = q.iter().unwrap().next().unwrap();
1090+
c.next().unwrap();
1091+
c.next().unwrap();
1092+
c.next().unwrap();
1093+
assert!(c.next().is_none());
1094+
}
10961095
}
10971096
}
10981097

0 commit comments

Comments
 (0)