Skip to main content

FutureQueue

Struct FutureQueue 

Source
pub struct FutureQueue<ST: SyncTypes, T: Send, F: QueuedFuture<T>> { /* private fields */ }
Expand description

Process futures one after another, providing each exclusive access to some “arbitrated ressource”.

From a functionality perspective, a FutureQueue is very similar to an asynchronous lock, where the lock is typically to be locked via polling and the owner can then subsequently keep it for an indefinite amount of time, e.g. across multiple poll() invocations on some other Futures, until eventually releasing the lock again and waking other waiters. However, this asynchronous lock scheme has the drawback that it is not robust against threads “loosing interest”, e.g. tasks abandoned for some reason: if the execution environment happens to not poll some lock owning task any further, all other waiting tasks would end up stuck for forever.

A FutureQueue solves this problem by assuming ownership of any future needing access to the protected ressource and providing that (exclusively) to its poll() once it becomes first in line. The important point is that any poll() on an enqueued future’s associated subscriptions will always drive progress for any other enqueued futures ahead in line, even if their original submitters ceased the polling. That way, any thread polling on its enqueued future’s associated subscription is guaranteed that its future will eventually get processed.

As the enqueued future’s poll() had to get extended in order to provide access to the FutureQueue arbitrated ressource, a new trait QueuedFuture, otherwise resembling that of a standard Rust Future is being defined. Users may enqueue implementations thereof via FutureQueue::enqueue() and subsequently poll on the resulting EnqueuedFutureSubscription to drive their respective enqueued future’s progress forward and eventually retrieve its result once Ready.

Implementations§

Source§

impl<ST: SyncTypes, T: Send, F: QueuedFuture<T>> FutureQueue<ST, T, F>

Source

pub fn new(arbitrated_ressource: T) -> Self

Crate a new FutureQueue instance.

Note that the caller is supposed to move the returned BroadcastFuture into a pinned SyncRcPtr – the other parts of the API expect that.

§Arguments:
  • arbitrated_ressource - The value to serialize access to. Provided as a mut reference to enqueued future’s poll().
Source

pub fn get_arbitrated_ressource_mut(&mut self) -> &mut T

Access the wrapped arbitrated ressource through a mut reference on Self.

Source

pub fn enqueue<QP: SyncRcPtr<FutureQueue<ST, T, F>>>( this: Pin<QP>, fut: F, ) -> Result<EnqueuedFutureSubscription<ST, T, F, QP>, (F, FutureQueueError)>

Enqueue a future.

On success, a EnqueuedFutureSubscription will get returned, which may get poll()ed to drive the future’s progress forward and to eventually obtain its result.

On error, the future instance will get returned back to the caller alongside some error information. Note that returning the future back enables the caller to recover objects whose ownership had been passed temporarily into the future.

§Arguments:

Trait Implementations§

Source§

impl<ST: SyncTypes, T: Send, F: QueuedFuture<T>> Send for FutureQueue<ST, T, F>

Source§

impl<ST: SyncTypes, T: Send, F: QueuedFuture<T>> Sync for FutureQueue<ST, T, F>

Auto Trait Implementations§

§

impl<ST, T, F> !Freeze for FutureQueue<ST, T, F>

§

impl<ST, T, F> !RefUnwindSafe for FutureQueue<ST, T, F>

§

impl<ST, T, F> Unpin for FutureQueue<ST, T, F>
where BroadcastWakerSubscriptions<ST>: Unpin, <ST as SyncTypes>::Lock<FutureQueueState<T, F>>: Unpin, UnsafeCell<Option<F>>: Unpin, UnsafeCell<T>: Unpin,

§

impl<ST, T, F> UnsafeUnpin for FutureQueue<ST, T, F>
where BroadcastWakerSubscriptions<ST>: UnsafeUnpin, <ST as SyncTypes>::Lock<FutureQueueState<T, F>>: UnsafeUnpin, UnsafeCell<Option<F>>: UnsafeUnpin, UnsafeCell<T>: UnsafeUnpin,

§

impl<ST, T, F> UnwindSafe for FutureQueue<ST, T, F>
where BroadcastWakerSubscriptions<ST>: UnwindSafe, <ST as SyncTypes>::Lock<FutureQueueState<T, F>>: UnwindSafe, UnsafeCell<Option<F>>: UnwindSafe, UnsafeCell<T>: UnwindSafe,

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, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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.