Something went wrong. Try again.
A hardware-accelerated GPU terminal emulator focusing to run in desktops and browsers.
Something went wrong. Try again.
2.2 kB · 102 lines
Rust
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103use std::error::Error;use std::fmt::{self, Display, Formatter};use std::future::Future;use std::pin::Pin;use std::sync::atomic::{AtomicBool, Ordering};use std::sync::Arc;use std::task::{Context, Poll};
use pin_project::pin_project;
use super::AtomicWaker;
#[pin_project]pub struct Abortable<F: Future> { #[pin] future: F, shared: Arc<Shared>,}
impl<F: Future> Abortable<F> { pub fn new(handle: AbortHandle, future: F) -> Self { Self { future, shared: handle.0, } }}
impl<F: Future> Future for Abortable<F> { type Output = Result<F::Output, Aborted>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { if self.shared.aborted.load(Ordering::Relaxed) { return Poll::Ready(Err(Aborted)); }
if let Poll::Ready(value) = self.as_mut().project().future.poll(cx) { return Poll::Ready(Ok(value)); }
self.shared.waker.register(cx.waker());
if self.shared.aborted.load(Ordering::Relaxed) { return Poll::Ready(Err(Aborted)); }
Poll::Pending }}
#[derive(Debug)]struct Shared { waker: AtomicWaker, aborted: AtomicBool,}
#[derive(Clone, Debug)]pub struct AbortHandle(Arc<Shared>);
impl AbortHandle { pub fn new() -> Self { Self(Arc::new(Shared { waker: AtomicWaker::new(), aborted: AtomicBool::new(false), })) }
pub fn abort(&self) { self.0.aborted.store(true, Ordering::Relaxed); self.0.waker.wake() }}
#[derive(Debug)]pub struct DropAbortHandle(AbortHandle);
impl DropAbortHandle { pub fn new(handle: AbortHandle) -> Self { Self(handle) }
pub fn handle(&self) -> AbortHandle { self.0.clone() }}
impl Drop for DropAbortHandle { fn drop(&mut self) { self.0.abort() }}
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]pub struct Aborted;
impl Display for Aborted { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "`Abortable` future has been aborted") }}
impl Error for Aborted {}