use crate::core::{ClNullEventPtr, Mem, MemMap as MemMapCore, OclPrm};
use crate::error::{Error as OclError, Result as OclResult};
use crate::r#async::MemMap;
use crate::{Event, EventList, Queue};
use futures::{Async, Future, Poll};
#[must_use = "futures do nothing unless polled"]
#[derive(Debug)]
pub struct FutureMemMap<T: OclPrm> {
core: Option<MemMapCore<T>>,
len: usize,
map_event: Event,
unmap_wait_events: Option<EventList>,
unmap_event: Option<Event>,
buffer: Option<Mem>,
queue: Option<Queue>,
callback_is_set: bool,
}
impl<T: OclPrm> FutureMemMap<T> {
pub unsafe fn new(
core: MemMapCore<T>,
len: usize,
map_event: Event,
buffer: Mem,
queue: Queue,
) -> FutureMemMap<T> {
FutureMemMap {
core: Some(core),
len,
map_event,
unmap_wait_events: None,
unmap_event: None,
buffer: Some(buffer),
queue: Some(queue),
callback_is_set: false,
}
}
pub fn set_unmap_wait_events<El>(&mut self, wait_events: El)
where
El: Into<EventList>,
{
self.unmap_wait_events = Some(wait_events.into())
}
pub fn ewait_unmap<L: Into<EventList>>(mut self, wait_events: L) -> FutureMemMap<T> {
self.set_unmap_wait_events(wait_events);
self
}
pub fn create_unmap_event(&mut self) -> OclResult<&mut Event> {
if let Some(ref queue) = self.queue {
let uev = Event::user(&queue.context())?;
self.unmap_event = Some(uev);
Ok(self.unmap_event.as_mut().unwrap())
} else {
Err("FutureMemMap::create_unmap_event: No queue found!".into())
}
}
pub fn enew_unmap<En>(mut self, mut enew: En) -> FutureMemMap<T>
where
En: ClNullEventPtr,
{
{
let unmap_event = self.create_unmap_event().expect("FutureMemMap::enew_unmap");
unsafe {
enew.clone_from(unmap_event);
}
}
self
}
pub fn set_unmap_queue(&mut self, queue: Queue) {
self.queue = Some(queue)
}
pub fn with_unmap_queue(mut self, queue: Queue) -> FutureMemMap<T> {
self.set_unmap_queue(queue);
self
}
#[inline]
pub fn unmap_event(&self) -> Option<&Event> {
self.unmap_event.as_ref()
}
pub fn wait(self) -> OclResult<MemMap<T>> {
<Self as Future>::wait(self)
}
fn to_mapped_mem(&mut self) -> OclResult<MemMap<T>> {
match (self.core.take(), self.buffer.take(), self.queue.take()) {
(Some(core), Some(buffer), Some(queue)) => {
unsafe {
Ok(MemMap::new(
core,
self.len,
self.unmap_wait_events.take(),
self.unmap_event.take(),
buffer,
queue,
))
}
}
_ => Err("FutureMemMap::create_unmap_event: No queue and/or buffer found!".into()),
}
}
}
#[cfg(not(feature = "async_block"))]
impl<T> Future for FutureMemMap<T>
where
T: OclPrm + 'static,
{
type Item = MemMap<T>;
type Error = OclError;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
match self.map_event.is_complete() {
Ok(true) => self.to_mapped_mem().map(|mm| Async::Ready(mm)),
Ok(false) => {
if !self.callback_is_set {
self.map_event.set_unpark_callback()?;
self.callback_is_set = true;
}
Ok(Async::NotReady)
}
Err(err) => Err(err.into()),
}
}
}
#[cfg(feature = "async_block")]
impl<T: OclPrm> Future for FutureMemMap<T> {
type Item = MemMap<T>;
type Error = OclError;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
let _ = self.callback_is_set;
self.map_event.wait_for()?;
self.to_mapped_mem().map(|mm| Async::Ready(mm))
}
}
unsafe impl<T: OclPrm> Send for FutureMemMap<T> {}
unsafe impl<T: OclPrm> Sync for FutureMemMap<T> {}