use crate::darc::Darc;
use std::pin::Pin;
use std::task::{Context, Poll};
use super::SharedMemoryRegion;
use crate::lamellae::Remote;
use crate::scheduler::LamellarTask;
use crate::warnings::RuntimeWarning;
use crate::LamellarTeamRT;
use futures_util::Future;
use pin_project::{pin_project, pinned_drop};
#[must_use = " SharedMemoryRegion 'new' handles do nothing unless polled or awaited, or 'spawn()' or 'block()' are called"]
#[pin_project(PinnedDrop)]
#[doc(alias = "Collective")]
pub struct FallibleSharedMemoryRegionHandle<T: Remote> {
pub(crate) team: Darc<LamellarTeamRT>,
pub(crate) launched: bool,
#[pin]
pub(crate) creation_future:
Pin<Box<dyn Future<Output = Result<SharedMemoryRegion<T>, anyhow::Error>> + Send>>,
}
#[pinned_drop]
impl<T: Remote> PinnedDrop for FallibleSharedMemoryRegionHandle<T> {
fn drop(self: Pin<&mut Self>) {
if !self.launched {
RuntimeWarning::DroppedHandle("a FallibleSharedMemoryRegionHandle").print();
}
}
}
impl<T: Remote> FallibleSharedMemoryRegionHandle<T> {
pub fn block(mut self) -> Result<SharedMemoryRegion<T>, anyhow::Error> {
self.launched = true;
RuntimeWarning::BlockingCall(
"SharedMemoryRegionHandle::block",
"<handle>.spawn() or<handle>.await",
)
.print();
self.team.clone().block_on(self)
}
#[must_use = "this function returns a future [LamellarTask] used to poll for completion. Call '.await' on the returned future in an async context or '.block()' in a non async context. Alternatively it may be acceptable to call '.block()' instead of 'spawn()' on this handle"]
pub fn spawn(mut self) -> LamellarTask<Result<SharedMemoryRegion<T>, anyhow::Error>> {
self.launched = true;
self.team.clone().spawn(self)
}
}
impl<T: Remote> Future for FallibleSharedMemoryRegionHandle<T> {
type Output = Result<SharedMemoryRegion<T>, anyhow::Error>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
self.launched = true;
let mut this = self.project();
this.creation_future.as_mut().poll(cx)
}
}
#[must_use = " SharedMemoryRegion 'new' handles do nothing unless polled or awaited, or 'spawn()' or 'block()' are called"]
#[pin_project(PinnedDrop)]
#[doc(alias = "Collective")]
pub struct SharedMemoryRegionHandle<T: Remote> {
pub(crate) team: Darc<LamellarTeamRT>,
pub(crate) launched: bool,
#[pin]
pub(crate) creation_future: Pin<Box<dyn Future<Output = SharedMemoryRegion<T>> + Send>>,
}
#[pinned_drop]
impl<T: Remote> PinnedDrop for SharedMemoryRegionHandle<T> {
fn drop(self: Pin<&mut Self>) {
if !self.launched {
RuntimeWarning::DroppedHandle("a SharedMemoryRegionHandle").print();
}
}
}
impl<T: Remote> SharedMemoryRegionHandle<T> {
pub fn block(mut self) -> SharedMemoryRegion<T> {
self.launched = true;
RuntimeWarning::BlockingCall(
"SharedMemoryRegionHandle::block",
"<handle>.spawn() or<handle>.await",
)
.print();
self.team.clone().block_on(self)
}
#[must_use = "this function returns a future [LamellarTask] used to poll for completion. Call '.await' on the returned future in an async context or '.block()' in a non async context. Alternatively it may be acceptable to call '.block()' instead of 'spawn()' on this handle"]
pub fn spawn(mut self) -> LamellarTask<SharedMemoryRegion<T>> {
self.launched = true;
self.team.clone().spawn(self)
}
}
impl<T: Remote> Future for SharedMemoryRegionHandle<T> {
type Output = SharedMemoryRegion<T>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
self.launched = true;
let mut this = self.project();
this.creation_future.as_mut().poll(cx)
}
}