Skip to content

Commit e7ac3b6

Browse files
committed
Implement Clone for IoManager
Implement Clone for IoManager, which will be needed for RCU-style device hotplug. Liu Jiang <[email protected]>
1 parent 5bd69ad commit e7ac3b6

File tree

1 file changed

+40
-1
lines changed

1 file changed

+40
-1
lines changed

src/device_manager.rs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ impl PartialOrd for IoRange {
7474
}
7575

7676
/// System IO manager serving for all devices management and VM exit handling.
77-
#[derive(Default)]
77+
#[derive(Clone, Default)]
7878
pub struct IoManager {
7979
/// Range mapping for VM exit pio operations.
8080
pio_bus: BTreeMap<IoRange, Arc<dyn DeviceIo>>,
@@ -276,6 +276,45 @@ mod tests {
276276
}
277277
}
278278

279+
#[test]
280+
fn test_clone_io_manager() {
281+
let mut io_mgr = IoManager::new();
282+
let dummy = DummyDevice::new(0);
283+
let dum = Arc::new(dummy);
284+
285+
let mut resource: Vec<Resource> = Vec::new();
286+
let mmio = Resource::MmioAddressRange {
287+
base: MMIO_ADDRESS_BASE,
288+
size: MMIO_ADDRESS_SIZE,
289+
};
290+
let pio = Resource::PioAddressRange {
291+
base: PIO_ADDRESS_BASE,
292+
size: PIO_ADDRESS_SIZE,
293+
};
294+
let irq = Resource::LegacyIrq(LEGACY_IRQ);
295+
296+
resource.push(mmio);
297+
resource.push(pio);
298+
resource.push(irq);
299+
assert!(io_mgr.register_device_io(dum.clone(), &resource).is_ok());
300+
301+
let io_mgr2 = io_mgr.clone();
302+
assert_eq!(io_mgr2.pio_bus.len(), 1);
303+
assert_eq!(io_mgr2.mmio_bus.len(), 1);
304+
305+
let (dev, addr) = io_mgr2
306+
.get_device(IoAddress::Mmio(MMIO_ADDRESS_BASE + 1))
307+
.unwrap();
308+
assert_eq!(Arc::strong_count(dev), 5);
309+
assert_eq!(addr, IoAddress::Mmio(MMIO_ADDRESS_BASE));
310+
311+
drop(io_mgr);
312+
assert_eq!(Arc::strong_count(dev), 3);
313+
314+
drop(io_mgr2);
315+
assert_eq!(Arc::strong_count(&dum), 1);
316+
}
317+
279318
#[test]
280319
fn test_register_unregister_device_io() {
281320
let mut io_mgr = IoManager::new();

0 commit comments

Comments
 (0)