Skip to content

Commit 3f36261

Browse files
committed
Add new method as_any() to GuestAddressSpace
Add new method as_any() to GuestAddressSpace, which returns reference to a std::any::Any trait object. Then downcast_ref() could be used to get the concrete type of GuestAddressSpace trait object. Signed-off-by: Liu Jiang <gerry@linux.alibaba.com>
1 parent c66e561 commit 3f36261

File tree

3 files changed

+56
-5
lines changed

3 files changed

+56
-5
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# Changelog
22
## [Unreleased]
33

4+
- [[192]](https://github.com/rust-vmm/vm-memory/pull/192): Add new method
5+
as_any() to GuestAddressSpace
6+
47
## [v0.7.0]
58

69
### Changed

src/atomic.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
extern crate arc_swap;
1313

1414
use arc_swap::{ArcSwap, Guard};
15+
use std::any::Any;
1516
use std::ops::Deref;
1617
use std::sync::{Arc, LockResult, Mutex, MutexGuard, PoisonError};
1718

@@ -75,13 +76,17 @@ impl<M: GuestMemory> GuestMemoryAtomic<M> {
7576
}
7677
}
7778

78-
impl<M: GuestMemory> GuestAddressSpace for GuestMemoryAtomic<M> {
79-
type T = GuestMemoryLoadGuard<M>;
79+
impl<M: GuestMemory + 'static> GuestAddressSpace for GuestMemoryAtomic<M> {
8080
type M = M;
81+
type T = GuestMemoryLoadGuard<M>;
8182

8283
fn memory(&self) -> Self::T {
8384
GuestMemoryLoadGuard { guard: self.load() }
8485
}
86+
87+
fn as_any(&self) -> &dyn Any {
88+
self
89+
}
8590
}
8691

8792
/// A guard that provides temporary access to a `GuestMemoryAtomic`. This
@@ -148,6 +153,23 @@ mod tests {
148153
type GuestRegionMmap = crate::GuestRegionMmap<()>;
149154
type GuestMemoryMmapAtomic = GuestMemoryAtomic<GuestMemoryMmap>;
150155

156+
#[test]
157+
fn test_as_any() {
158+
let region_size = 0x400;
159+
let regions = vec![
160+
(GuestAddress(0x0), region_size),
161+
(GuestAddress(0x1000), region_size),
162+
];
163+
let gmm = GuestMemoryMmap::from_ranges(&regions).unwrap();
164+
let gm = GuestMemoryMmapAtomic::new(gmm);
165+
166+
assert!(gm
167+
.as_any()
168+
.downcast_ref::<GuestMemoryMmapAtomic>()
169+
.is_some());
170+
assert!(gm.as_any().downcast_ref::<String>().is_none());
171+
}
172+
151173
#[test]
152174
fn test_atomic_memory() {
153175
let region_size = 0x400;

src/guest_memory.rs

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
//! via pointers, references, or slices returned by methods of `GuestMemory`,`GuestMemoryRegion`,
4242
//! `VolatileSlice`, `VolatileRef`, or `VolatileArrayRef`.
4343
44+
use std::any::Any;
4445
use std::convert::From;
4546
use std::fmt::{self, Display};
4647
use std::fs::File;
@@ -400,33 +401,48 @@ pub trait GuestAddressSpace {
400401
/// to access memory through this address space. The object provides
401402
/// a consistent snapshot of the memory map.
402403
fn memory(&self) -> Self::T;
404+
405+
/// Cast `self` to a dynamic trait object of `std::any::Any`.
406+
fn as_any(&self) -> &dyn Any;
403407
}
404408

405-
impl<M: GuestMemory> GuestAddressSpace for &M {
409+
impl<M: GuestMemory + 'static> GuestAddressSpace for &M {
406410
type M = M;
407411
type T = Self;
408412

409413
fn memory(&self) -> Self {
410414
self
411415
}
416+
417+
fn as_any(&self) -> &dyn Any {
418+
*self
419+
}
412420
}
413421

414-
impl<M: GuestMemory> GuestAddressSpace for Rc<M> {
422+
impl<M: GuestMemory + 'static> GuestAddressSpace for Rc<M> {
415423
type M = M;
416424
type T = Self;
417425

418426
fn memory(&self) -> Self {
419427
self.clone()
420428
}
429+
430+
fn as_any(&self) -> &dyn Any {
431+
self
432+
}
421433
}
422434

423-
impl<M: GuestMemory> GuestAddressSpace for Arc<M> {
435+
impl<M: GuestMemory + 'static> GuestAddressSpace for Arc<M> {
424436
type M = M;
425437
type T = Self;
426438

427439
fn memory(&self) -> Self {
428440
self.clone()
429441
}
442+
443+
fn as_any(&self) -> &dyn Any {
444+
self
445+
}
430446
}
431447

432448
/// Lifetime generic associated iterators. The actual iterator type is defined through associated
@@ -1256,4 +1272,14 @@ mod tests {
12561272
let r = mem.find_region(addr).unwrap();
12571273
assert_eq!(r.is_hugetlbfs(), None);
12581274
}
1275+
1276+
#[cfg(feature = "backend-mmap")]
1277+
#[test]
1278+
fn test_as_any() {
1279+
let addr = GuestAddress(0x1000);
1280+
let mem = &GuestMemoryMmap::from_ranges(&[(addr, 0x1000)]).unwrap();
1281+
1282+
assert!(mem.as_any().downcast_ref::<GuestMemoryMmap>().is_some());
1283+
assert!(mem.as_any().downcast_ref::<String>().is_none());
1284+
}
12591285
}

0 commit comments

Comments
 (0)