gpu: don't use raw descriptors of resource bridges on Windows.

Resource bridges are not supported on Windows, so we shouldn't try
to add their raw descriptors in Gpu::keep_rds().

Struct Gpu is updated to hold the ResourceBridges struct rather
than the Vec<Tube>.

BUG=b:213149288
TEST=presubmit

Change-Id: I6b71076d17057728b927d93462e3aee29f3ac8af
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3911100
Commit-Queue: Pujun Lun <lunpujun@google.com>
Reviewed-by: Alexandre Courbot <acourbot@chromium.org>
diff --git a/devices/src/virtio/gpu/mod.rs b/devices/src/virtio/gpu/mod.rs
index 7408d49..b7736e1 100644
--- a/devices/src/virtio/gpu/mod.rs
+++ b/devices/src/virtio/gpu/mod.rs
@@ -12,7 +12,6 @@
 use std::collections::BTreeMap;
 use std::collections::VecDeque;
 use std::io::Read;
-use std::mem;
 use std::mem::size_of;
 use std::path::PathBuf;
 use std::rc::Rc;
@@ -920,7 +919,7 @@
 pub struct Gpu {
     exit_evt_wrtube: SendTube,
     mapper: Option<Box<dyn SharedMemoryMapper>>,
-    resource_bridges: Vec<Tube>,
+    resource_bridges: Option<ResourceBridges>,
     event_devices: Vec<EventDevice>,
     kill_evt: Option<Event>,
     config_event: bool,
@@ -1001,7 +1000,7 @@
         Gpu {
             exit_evt_wrtube,
             mapper: None,
-            resource_bridges,
+            resource_bridges: Some(ResourceBridges::new(resource_bridges)),
             event_devices,
             config_event: false,
             kill_evt: None,
@@ -1130,8 +1129,9 @@
         }
 
         keep_rds.push(self.exit_evt_wrtube.as_raw_descriptor());
-        for bridge in &self.resource_bridges {
-            keep_rds.push(bridge.as_raw_descriptor());
+
+        if let Some(resource_bridges) = &self.resource_bridges {
+            resource_bridges.append_raw_descriptors(&mut keep_rds);
         }
 
         keep_rds
@@ -1213,7 +1213,13 @@
         };
         self.kill_evt = Some(self_kill_evt);
 
-        let resource_bridges = ResourceBridges::new(mem::take(&mut self.resource_bridges));
+        let resource_bridges = match self.resource_bridges.take() {
+            Some(bridges) => bridges,
+            None => {
+                error!("resource_bridges is none");
+                return;
+            }
+        };
 
         let irq = Arc::new(interrupt);
         let ctrl_queue = SharedQueueReader::new(queues.remove(0), &irq);
@@ -1302,6 +1308,9 @@
 
 /// Trait that the platform-specific type `ResourceBridges` needs to implement.
 trait ResourceBridgesTrait {
+    // Appends raw descriptors of all resource bridges to the given vector.
+    fn append_raw_descriptors(&self, _rds: &mut Vec<RawDescriptor>);
+
     /// Adds all resource bridges to WaitContext.
     fn add_to_wait_context(&self, _wait_ctx: &mut WaitContext<WorkerToken>);
 
diff --git a/devices/src/virtio/gpu/sys/unix.rs b/devices/src/virtio/gpu/sys/unix.rs
index 68d827f..8a4e270 100644
--- a/devices/src/virtio/gpu/sys/unix.rs
+++ b/devices/src/virtio/gpu/sys/unix.rs
@@ -4,6 +4,8 @@
 
 use anyhow::Context;
 use base::error;
+use base::AsRawDescriptor;
+use base::RawDescriptor;
 use base::Tube;
 use base::WaitContext;
 use serde::Deserialize;
@@ -88,6 +90,12 @@
 }
 
 impl ResourceBridgesTrait for UnixResourceBridges {
+    fn append_raw_descriptors(&self, rds: &mut Vec<RawDescriptor>) {
+        for bridge in &self.resource_bridges {
+            rds.push(bridge.as_raw_descriptor());
+        }
+    }
+
     fn add_to_wait_context(&self, wait_ctx: &mut WaitContext<WorkerToken>) {
         for (index, bridge) in self.resource_bridges.iter().enumerate() {
             if let Err(e) = wait_ctx.add(bridge, WorkerToken::ResourceBridge { index }) {
diff --git a/devices/src/virtio/gpu/sys/windows.rs b/devices/src/virtio/gpu/sys/windows.rs
index 40b6264..cc107b2 100644
--- a/devices/src/virtio/gpu/sys/windows.rs
+++ b/devices/src/virtio/gpu/sys/windows.rs
@@ -5,6 +5,7 @@
 use std::marker::PhantomData;
 
 use base::info;
+use base::RawDescriptor;
 use base::Tube;
 use base::WaitContext;
 use serde::Deserialize;
@@ -103,6 +104,8 @@
 }
 
 impl ResourceBridgesTrait for WinResourceBridges {
+    fn append_raw_descriptors(&self, _rds: &mut Vec<RawDescriptor>) {}
+
     fn add_to_wait_context(&self, _wait_ctx: &mut WaitContext<WorkerToken>) {}
 
     fn set_should_process(&mut self, _index: usize) {}