From e746b6d80654ba4e4e26370fe6e4f784ce841d92 Mon Sep 17 00:00:00 2001 From: Matt Mastracci Date: Sat, 1 Jul 2023 18:00:14 -0600 Subject: refactor(core): Extract deno_core (#19658) `deno_core` is moving out! You'll find it at https://github.com/denoland/deno_core/ once this PR lands. --- core/task.rs | 135 ----------------------------------------------------------- 1 file changed, 135 deletions(-) delete mode 100644 core/task.rs (limited to 'core/task.rs') diff --git a/core/task.rs b/core/task.rs deleted file mode 100644 index 3e728a08f..000000000 --- a/core/task.rs +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -use core::pin::Pin; -use core::task::Context; -use core::task::Poll; -use futures::Future; -use std::marker::PhantomData; -use tokio::runtime::Handle; -use tokio::runtime::RuntimeFlavor; - -/// Equivalent to [`tokio::task::JoinHandle`]. -#[repr(transparent)] -pub struct JoinHandle { - handle: tokio::task::JoinHandle>, - _r: PhantomData, -} - -impl JoinHandle { - /// Equivalent to [`tokio::task::JoinHandle::abort`]. - pub fn abort(&self) { - self.handle.abort() - } -} - -impl Future for JoinHandle { - type Output = Result; - - fn poll( - self: Pin<&mut Self>, - cx: &mut std::task::Context<'_>, - ) -> std::task::Poll { - // SAFETY: We are sure that handle is valid here - unsafe { - let me: &mut Self = Pin::into_inner_unchecked(self); - let handle = Pin::new_unchecked(&mut me.handle); - match handle.poll(cx) { - Poll::Pending => Poll::Pending, - Poll::Ready(Ok(r)) => Poll::Ready(Ok(r.into_inner())), - Poll::Ready(Err(e)) => Poll::Ready(Err(e)), - } - } - } -} - -/// Equivalent to [`tokio::task::spawn`], but does not require the future to be [`Send`]. Must only be -/// used on a [`RuntimeFlavor::CurrentThread`] executor, though this is only checked when running with -/// debug assertions. -#[inline(always)] -pub fn spawn + 'static, R: 'static>( - f: F, -) -> JoinHandle { - debug_assert!( - Handle::current().runtime_flavor() == RuntimeFlavor::CurrentThread - ); - // SAFETY: we know this is a current-thread executor - let future = unsafe { MaskFutureAsSend::new(f) }; - JoinHandle { - handle: tokio::task::spawn(future), - _r: Default::default(), - } -} - -/// Equivalent to [`tokio::task::spawn_blocking`]. Currently a thin wrapper around the tokio API, but this -/// may change in the future. -#[inline(always)] -pub fn spawn_blocking< - F: (FnOnce() -> R) + Send + 'static, - R: Send + 'static, ->( - f: F, -) -> JoinHandle { - let handle = tokio::task::spawn_blocking(|| MaskResultAsSend { result: f() }); - JoinHandle { - handle, - _r: Default::default(), - } -} - -#[repr(transparent)] -#[doc(hidden)] -pub struct MaskResultAsSend { - result: R, -} - -/// SAFETY: We ensure that Send bounds are only faked when tokio is running on a current-thread executor -unsafe impl Send for MaskResultAsSend {} - -impl MaskResultAsSend { - #[inline(always)] - pub fn into_inner(self) -> R { - self.result - } -} - -#[repr(transparent)] -pub struct MaskFutureAsSend { - future: F, -} - -impl MaskFutureAsSend { - /// Mark a non-`Send` future as `Send`. This is a trick to be able to use - /// `tokio::spawn()` (which requires `Send` futures) in a current thread - /// runtime. - /// - /// # Safety - /// - /// You must ensure that the future is actually used on the same - /// thread, ie. always use current thread runtime flavor from Tokio. - #[inline(always)] - pub unsafe fn new(future: F) -> Self { - Self { future } - } -} - -// SAFETY: we are cheating here - this struct is NOT really Send, -// but we need to mark it Send so that we can use `spawn()` in Tokio. -unsafe impl Send for MaskFutureAsSend {} - -impl Future for MaskFutureAsSend { - type Output = MaskResultAsSend; - - fn poll( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll> { - // SAFETY: We are sure that future is valid here - unsafe { - let me: &mut MaskFutureAsSend = Pin::into_inner_unchecked(self); - let future = Pin::new_unchecked(&mut me.future); - match future.poll(cx) { - Poll::Pending => Poll::Pending, - Poll::Ready(result) => Poll::Ready(MaskResultAsSend { result }), - } - } - } -} -- cgit v1.2.3