浏览代码

Add helper to iterate over all buffers rather than repeating code.

Andrew Walbran 2 年之前
父节点
当前提交
9c4b422194
共有 1 个文件被更改,包括 26 次插入10 次删除
  1. 26 10
      src/queue.rs

+ 26 - 10
src/queue.rs

@@ -114,17 +114,15 @@ impl<H: Hal> VirtQueue<H> {
         // Safe because self.desc is properly aligned, dereferenceable and initialised, and nothing
         // else reads or writes the free descriptors during this block.
         unsafe {
-            for input in inputs.iter() {
-                let mut desc = self.desc_ptr(self.free_head);
-                (*desc).set_buf::<H>(NonNull::new(*input as *mut [u8]).unwrap());
-                (*desc).flags = DescFlags::NEXT;
-                last = self.free_head;
-                self.free_head = (*desc).next;
-            }
-            for output in outputs.iter() {
+            for (buffer, is_output) in input_output_iter(inputs, outputs) {
                 let desc = self.desc_ptr(self.free_head);
-                (*desc).set_buf::<H>(NonNull::new(*output).unwrap());
-                (*desc).flags = DescFlags::NEXT | DescFlags::WRITE;
+                (*desc).set_buf::<H>(buffer);
+                (*desc).flags = DescFlags::NEXT
+                    | if is_output {
+                        DescFlags::WRITE
+                    } else {
+                        DescFlags::empty()
+                    };
                 last = self.free_head;
                 self.free_head = (*desc).next;
             }
@@ -526,3 +524,21 @@ mod tests {
         }
     }
 }
+
+/// Returns an iterator over the buffers of first `inputs` and then `outputs`, paired with the
+/// corresponding `BufferDirection`.
+///
+/// Panics if any of the buffer pointers is null.
+fn input_output_iter<'a>(
+    inputs: &'a [*const [u8]],
+    outputs: &'a [*mut [u8]],
+) -> impl Iterator<Item = (NonNull<[u8]>, bool)> + 'a {
+    inputs
+        .iter()
+        .map(|input| (NonNull::new(*input as *mut [u8]).unwrap(), false))
+        .chain(
+            outputs
+                .iter()
+                .map(|output| (NonNull::new(*output).unwrap(), true)),
+        )
+}