-
Notifications
You must be signed in to change notification settings - Fork 59
Description
See jamesmunns/bbq2#2 for the full context, but the TL;DR is that if you are writing your own implementation of Storage, Coord or Notifier it tends to be very useful (if not outright necessary) to get at least shared access to them in some way.
Mutable access if you have &mut BBQueue might be worthwhile to think about too?
(Like it available with &mut Mutex::get_mut() for example)
I would propose to solve this by adding unsafe accessors like this to BBQueue:
impl BBQueue {
pub unsafe fn coord(&self) -> Self::Coord {
self.coord
}
pub unsafe fn storage(&self) -> Self::Storage {
self.storage
}
pub unsafe fn notifier(&self) -> Self::Notifier {
self.notifier
}
}Though I could also imagine a .components() method like this:
impl<H: BbqHandle> BBQueue {
pub unsafe components(&self) -> BbqComponents<'_, H::Storage, H::Coord, H::Notifier> {
// skip..
}
}
pub struct BbqComponents<'a, H: BbqHandle> {
pub storage: &'a Storage,
pub coord: &'a Coord,
pub notifier: &'a Notifier,
pub _marker: PhantomData<H>,
}For the same reason as to why I added BbqHandle in the first place that impl should then also include a type Components = BbqComponents<'_, H::Storage, H::Coord, H::Notifier> "type alias" on BbqHandle.
If/When unsafe fields are stabilized, it might also be reasonable to think about making BBQueue fields itself pub unsafe. They should be a stable interface anyway as changing them would probably imply having to break most of the public API too.
An adjacent concern would be to decide whether to add a constructor for BBQueue to let the user construct the components themselves.
Note that in the original PR there also were an interface to make the futures of adaptors like FramedProducer nameable, but honestly I don't think anymore that this extra work is actually necessary.
If you can call .wait_grant(), you might as well just get yourself a ref to the BBQueue directly.
Though if that actually ends up being useful for someone, I do have a cool little idea of how one could use a struct BBQFuture { handle, fut: async { /** Your async code here! **/ } } instead of the mess of an API I came up in jamesmunns/bbq2#2
The resulting type would technically not be nameable, but that is usually not actually a problem. At most an inconvenience.