use std::{
future::IntoFuture,
sync::Arc,
};
use qubit_executor::{
CancelResult,
TaskResult,
TaskStatus,
TrackedTask,
TryGet,
task::{
TaskHandleFuture,
spi::{
TaskResultHandle,
TrackedTaskHandle,
},
},
};
use crate::{
pending_cancel::PendingCancel,
rayon_executor_service_state::RayonExecutorServiceState,
};
pub struct RayonTaskHandle<R, E> {
inner: TrackedTask<R, E>,
task_id: usize,
state: Arc<RayonExecutorServiceState>,
cancel: PendingCancel,
}
impl<R, E> RayonTaskHandle<R, E> {
pub(crate) fn new(
inner: TrackedTask<R, E>,
task_id: usize,
state: Arc<RayonExecutorServiceState>,
cancel: PendingCancel,
) -> Self {
Self {
inner,
task_id,
state,
cancel,
}
}
#[inline]
pub fn get(self) -> TaskResult<R, E>
where
R: Send,
E: Send,
{
self.inner.get()
}
#[inline]
pub fn try_get(self) -> TryGet<Self, R, E>
where
R: Send,
E: Send,
{
<Self as TaskResultHandle<R, E>>::try_get(self)
}
#[inline]
pub fn cancel(&self) -> CancelResult
where
R: Send,
E: Send,
{
<Self as TrackedTaskHandle<R, E>>::cancel(self)
}
#[inline]
pub fn is_done(&self) -> bool
where
R: Send,
E: Send,
{
<Self as TaskResultHandle<R, E>>::is_done(self)
}
#[inline]
pub fn status(&self) -> TaskStatus {
self.inner.status()
}
}
impl<R, E> TaskResultHandle<R, E> for RayonTaskHandle<R, E>
where
R: Send,
E: Send,
{
#[inline]
fn is_done(&self) -> bool {
self.inner.is_done()
}
#[inline]
fn get(self) -> TaskResult<R, E> {
self.inner.get()
}
#[inline]
fn try_get(self) -> TryGet<Self, R, E> {
let Self {
inner,
task_id,
state,
cancel,
} = self;
match inner.try_get() {
TryGet::Ready(result) => TryGet::Ready(result),
TryGet::Pending(inner) => TryGet::Pending(Self {
inner,
task_id,
state,
cancel,
}),
}
}
}
impl<R, E> TrackedTaskHandle<R, E> for RayonTaskHandle<R, E>
where
R: Send,
E: Send,
{
#[inline]
fn status(&self) -> TaskStatus {
self.inner.status()
}
#[inline]
fn cancel(&self) -> CancelResult {
if self.state.cancel_pending_task(self.task_id, &self.cancel) {
return CancelResult::Cancelled;
}
match self.status() {
TaskStatus::Pending => CancelResult::Unsupported,
TaskStatus::Running => CancelResult::AlreadyRunning,
_ => CancelResult::AlreadyFinished,
}
}
}
impl<R, E> IntoFuture for RayonTaskHandle<R, E> {
type Output = TaskResult<R, E>;
type IntoFuture = TaskHandleFuture<R, E>;
#[inline]
fn into_future(self) -> Self::IntoFuture {
self.inner.into_future()
}
}