So I'm trying to figure out how to store async fns (I tried to implement a spawn() function on my executor but I can't figure out how to do it from the way its designed, and I'm working in a no_std environment and I don't have threads). I've tried this type alias:
type InitFunc = Box<dyn Fn(PciDevice) -> Pin<Box<Pin<dyn Future<Output = ()>>>>+Send+Sync>;
However, Rust complains that (dyn Future<Output = ()> + 'static)
's size isn't known when I try to store this in a HashMap. My executor, as its currently written, defines futures as Pin<Box<dyn Future<Output = ()>>>
. If I redefine my type alias as Pin<Box<dyn Future<Output = ()>+Send+Sync>>
, Rust first tells me that &Pin<alloc::boxed::Box<dyn Future<Output = ()> + Send + Sync>>
isn't a function, even if dereference it, then it goes on to say that fn(PciDevice) -> impl Future {nvme::init}
is not a future. So I'm horribly confused (I do have the init() function defined as async...). For reference I'm trying to store it in a hash map:
lazy_static! {
static ref PCI_DEVICES: RwLock<MiniVec<PciDevice>> = RwLock::new(MiniVec::new());
static ref DEV_INIT_FUNCS: RwLock<HashMap<DeviceIdentification, InitFunc>> = RwLock::new({
let mut map: HashMap<DeviceIdentification, InitFunc> = HashMap::new();
if cfg!(feature = "nvme") {
use minivec::mini_vec;
let dinfo = mini_vec![(0x01, 0x08, 0x02), (0x01, 0x08, 0x03)];
map.insert(dinfo, Box::pin(crate::nvme::init));
}
map
});
}
So I can then call it later:
let funcs = DEV_INIT_FUNCS.read();
for (k, v) in funcs.iter() {
let devs: MiniVec<&DeviceInformation> = k.iter().filter(|dinfo| read_byte(addr as usize, DEV_CLASS) == dinfo.0 && read_byte(addr as usize, DEV_SUBCLASS) == dinfo.1 && read_byte(addr as usize, PROG_IF) == dinfo.2).collect();
if !devs.is_empty() {
info!("Found device driver for class={:X}, subclass={:X}, program interface={:X}; initializing", dev.class, dev.subclass, dev.prog_if);
*v(dev).await;
}
}
So I'm really not sure what's going wrong with this one.