Skip to main content

AsyncTask

Struct AsyncTask 

Source
pub struct AsyncTask<P: AsyncTaskPoolExt<O> + AsyncTaskPool<O>, O: Default + 'static = ()> { /* private fields */ }
Expand description

异步任务及其运行时调度/生命周期状态。

§运行时契约

运行时托管任务是一次性的:其 Future 被持续轮询,首次返回 Ready 后永久完成。 运行时任务通过私有原子状态合并重复唤醒、排除并发轮询,并拒绝迟到唤醒。公开 get_inner/set_inner 选择旧手工驱动契约,包括显式的低层替换/复用能力,因此 既有自定义驱动无需新增特征方法。

构造函数只创建一个逻辑上的首次轮询义务,并不执行物理入队。运行时或自定义任务池 必须通过既有 push* 接口把新任务准确入队一次。Waker 用于在首次提交后安排后续 轮询,不能替代首次入队。

§示例

use std::sync::Arc;
use futures::FutureExt;
use pi_async_rt::rt::{
    AsyncRuntime, AsyncTask, AsyncTaskPool,
    single_thread::SingleTaskRunner,
};

let runner = SingleTaskRunner::<()>::default();
let runtime = runner.startup().unwrap();
let task = Arc::new(AsyncTask::new(
    runtime.alloc::<()>(),
    runtime.shared_pool(),
    0,
    Some(async {}.boxed()),
));
runtime.shared_pool().push(task).unwrap();
runner.run_once().unwrap();

future 锁只覆盖取出或恢复装箱的 Future;绝不会跨越 Future::poll、任务池访问、 工作线程通知、用户回调/析构、I/O 或 FFI。运行时状态操作为 O(1)、无分配且无锁, 但比较并交换循环不具备无等待性,在竞争唤醒/轮询状态持续推进时可能重试。任务不是 repr(C),不提供稳定的 FFI/Rust 布局 ABI。

§布局与内存

在已验收的 x86_64 目标上,加入内联调度状态后, AsyncTask<StealableTaskPool<()>, ()> 为 96 字节,之前的实现为 80 字节。 一字节状态跨过了该特化的 16 字节对齐边界,因此实际内联增量是 16 字节,而不是 一字节。百万个同时存活的任务会增加 16,000,000 字节(约 15.26 MiB)任务本体 存储。这是并发存活/保留成本,不会按历史累计执行过的任务数增长。

状态不会新增独立堆分配。Arc 管理信息、装箱的 Future、任务句柄、context 负载和 队列存储仍是独立的既有成本,不包含在 96 字节本体内。分配器尺寸分级和队列 容量会使实际 RSS 与逻辑本体增量不同。若要把本体恢复到 80 字节,需要重新组织 context/state 表示;该优化会触及 V8 敏感的所有权表示,必须单独设计、审查和 验证下游,因此本轮明确延期。

§安全性

托管轮询所有权由 state 同步,Future 所有权由 future 同步。既有 TaskId 和 context 安全要求不变。调用方不得并发手工轮询同一任务,也不得从任务池窃取 运行时所有的任务。

Implementations§

Source§

impl<P: AsyncTaskPoolExt<O> + AsyncTaskPool<O, Pool = P>, O: Default + 'static> AsyncTask<P, O>

Source

pub fn new( uid: TaskId, pool: Arc<P>, priority: usize, future: Option<BoxFuture<'static, O>>, ) -> AsyncTask<P, O>

构造一个一次性异步任务。

任务初始带有一个托管轮询义务。若任务进入本库运行时,私有驱动会保证唤醒 合并和独占轮询。调用公开 get_innerset_inner 会选择旧手工驱动模式, 但不改变这两个方法的签名或值语义。

构造时间复杂度为 O(1),除参数已经拥有的值外不新增分配;不执行队列操作、 唤醒、轮询、加锁、I/O 或回调。每个值拥有一个 TaskId,因此构造不是幂等操作。

Source

pub fn with_context<C: 'static>( uid: TaskId, pool: Arc<P>, priority: usize, future: Option<BoxFuture<'static, O>>, context: C, ) -> AsyncTask<P, O>

构造一个带调用方 context 的一次性任务。

调度和唤醒语义与 AsyncTask::new 相同。本函数为 context 执行一次 Box 分配,因此构造的时间和空间复杂度均为 O(1)。它不入队、不轮询、不唤醒、 不获取运行时锁、不执行用户代码、不执行 I/O,也不接触 FFI。保存的 context 继续服从既有所有者线程/context 访问契约。

Source

pub fn with_runtime_and_context<RT, C>( runtime: &RT, priority: usize, future: Option<BoxFuture<'static, O>>, context: C, ) -> AsyncTask<P, O>
where RT: AsyncRuntime<O, Pool = P>, C: Send + 'static,

构造一个绑定到 runtime 且携带调用方 context 的任务。

返回值随后由本库运行时驱动消费时属于托管任务,这也包括 pi_v8::VmTaskPool 等外部定时器适配器。公开 get/set 仍会选择旧手工驱动。 构造为 O(1),执行既有 runtime.alloc TaskHandle 分配、一次 context Box 分配和一次共享任务池 Arc 克隆。分配失败继续保持这些既有操作的进程级行为。 本函数不入队、不轮询、不唤醒、不阻塞、不执行用户代码、I/O 或 FFI。

Source

pub fn is_enable_wakeup(&self) -> bool

检查是否允许唤醒

Source

pub fn get_inner(&self) -> Option<BoxFuture<'static, O>>

为外部/手工任务驱动取出装箱的 Future。

本方法在取出 Future 前选择兼容手工调度,因此既有自定义驱动无需新增特征 方法即可保留原有唤醒后调用 push_keep 的行为。本方法不是运行时驱动入口。

当其它驱动拥有 Future 或任务已完成时返回 None。时间复杂度 O(1),不分配; 只获取任务的短 Future 互斥锁,可能与其它 get/set 短暂竞争。不得与本库运行时驱动 并发调用,也不得用于并发轮询同一任务。本操作非纯、非幂等,并转移 Future 所有权。

Source

pub fn set_inner(&self, inner: Option<BoxFuture<'static, O>>)

为外部/手工任务驱动替换装箱的 Future。

本方法选择兼容手工调度,也允许显式复用已完成的低层任务,从而保留旧公开 get/set 能力。运行时所有的 Pending 恢复使用私有辅助函数,仍保持托管。复用已完成任务 前,手工驱动必须回收全部旧唤醒器;在保留的兼容手工契约下,旧唤醒器否则可能 把替换后的 Future 入队。

时间复杂度 O(1),除调用方拥有的装箱值外不分配;只获取短 Future 互斥锁,不轮询、 不入队也不唤醒。本操作非纯且非幂等。被替换的 Future 会先移出互斥锁临界区, 再在调用线程析构,因此其析构函数不能在持有 Future 锁时重入本任务。

Source

pub fn owner(&self) -> usize

获取任务的所有者

Source

pub fn priority(&self) -> usize

获取异步任务优先级

Source

pub fn exist_context(&self) -> bool

Source

pub fn get_context<C: Send + 'static>(&self) -> Option<&C>

Source

pub fn get_context_mut<C: Send + 'static>(&self) -> Option<&mut C>

Source

pub fn set_context<C: Send + 'static>(&self, new: C)

Source

pub fn get_pool(&self) -> &P

Trait Implementations§

Source§

impl<P: AsyncTaskPoolExt<O> + AsyncTaskPool<O, Pool = P>, O: Default + 'static> ArcWake for AsyncTask<P, O>

Source§

fn wake_by_ref(arc_self: &Arc<Self>)

发布一个可运行义务,并在需要时调度任务。

托管任务在已入队或运行时会合并重复唤醒。使空闲任务转为已调度状态的唤醒 准确执行一次 Arc 克隆、一次 push_keep,并且最多通知一个工作线程。运行中 的任务只记录延期调度;当前轮询所有者在恢复返回 Pending 的 Future 后入队。 对已完成任务的唤醒是空操作。

无竞争时的状态处理为 O(1) 且不新增分配;push_keep 继续服从具体任务池既有的 时间、容量和扩容成本。该路径不访问 Future 互斥锁,不阻塞等待,不执行用户回调、 I/O 或 FFI。无锁比较并交换循环不具备无等待性,在竞争状态持续推进时可能重试。 与修改前相同,为保证运行时活性,任务池的 push_keep 必须能够接受可运行任务。

Source§

fn wake(self: Arc<Self>)

Indicates that the associated task is ready to make progress and should be polled. Read more
Source§

impl<P: AsyncTaskPoolExt<O> + AsyncTaskPool<O>, O: Default + 'static> Drop for AsyncTask<P, O>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more
Source§

impl<P: AsyncTaskPoolExt<O> + AsyncTaskPool<O>, O: Default + 'static> Send for AsyncTask<P, O>

Source§

impl<P: AsyncTaskPoolExt<O> + AsyncTaskPool<O>, O: Default + 'static> Sync for AsyncTask<P, O>

Auto Trait Implementations§

§

impl<P, O = ()> !Freeze for AsyncTask<P, O>

§

impl<P, O = ()> !RefUnwindSafe for AsyncTask<P, O>

§

impl<P, O = ()> !UnwindSafe for AsyncTask<P, O>

§

impl<P, O> Unpin for AsyncTask<P, O>

§

impl<P, O> UnsafeUnpin for AsyncTask<P, O>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> ThreadSend for T
where T: Send,

Source§

impl<T> ThreadSync for T
where T: Sync + Send,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V