Skip to main content

Queue

Struct Queue 

Source
pub struct Queue { /* private fields */ }
Expand description

An explicit thread boundary.

Pushing into a Queue hands the buffer off through a bounded channel and returns immediately — it never blocks the caller on whatever is downstream (unless the channel is full and policy is Block). A dedicated worker thread owns everything downstream of the queue and drives it via direct Sink::consume calls, until it hits another Queue.

ControlMsg crosses this same thread boundary through a separate channel from data. The worker checks that channel before entering its combined wait on every iteration, so a control message already pending at that point jumps ahead of the data backlog. A control message that arrives in the narrow window after that check can race one ready data buffer in select!, but is checked again before another buffer is pulled. Every worker acks a control message before acting on it any further (e.g. before blocking on Pause), so the channel stays responsive to the next one — Resume/Stop always reaches a paused worker immediately, it’s never stuck behind the pause itself. See the worker loop below.

Cheap elements (e.g. a muxer sitting right after an encoder) should simply not have a Queue between them and their upstream — they run as a direct call on the upstream element’s thread instead of paying for a dedicated thread they don’t need.

A failing downstream.consume() doesn’t end the worker thread either — that buffer is dropped, BusEvent::Error is posted, and the loop moves on to the next one. This crate never decides an error is fatal on your behalf; watch crate::pipeline::Pipeline::bus and call crate::pipeline::Pipeline::stop yourself if a particular error means the whole pipeline should end.

Implementations§

Source§

impl Queue

Source

pub fn spawn( name: impl Into<String>, capacity: usize, downstream: Box<dyn Sink>, bus: Bus, pipeline_id: Option<&str>, ) -> Queue

Spawns with OverflowPolicy::default. Use Queue::spawn_with_policy to drop instead of blocking when full.

Source

pub fn spawn_with_policy( name: impl Into<String>, capacity: usize, downstream: Box<dyn Sink>, bus: Bus, policy: OverflowPolicy, pipeline_id: Option<&str>, ) -> Queue

Spawns the worker thread that owns downstream and starts pulling from the channel immediately. pipeline_id (typically the owning crate::pipeline::Pipeline’s own id — see crate::pipeline::ChainBuilder, which is what actually passes one when this Queue came from a .queue()/.queue_with_policy() call) becomes this Queue’s pp_log pipeline_id; None if it wasn’t built through a Pipeline at all (e.g. the tests below).

Trait Implementations§

Source§

impl Drop for Queue

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 Element for Queue

Source§

fn name(&self) -> Arc<str>

Returns a cheap clone (refcount bump, not a deep copy) of this element’s name — crate::bus::BusEvent stores names as Arc<str> for exactly this reason: a hot path like crate::queue::Queue posting BusEvent::Dropped once per overflowed buffer shouldn’t pay for a fresh heap allocation every time it wants to report which element it is.
Source§

fn element_type(&self) -> ElementType

Source§

fn pp_log(&self) -> &PpLog

This element’s identity for crate::bus::Bus::post — same id/name as Element::name, just already wrapped as the crate::pp_log::PpLog its pp_info!/pp_warn!/pp_error! macros need. A stored private field, not built fresh per call, for the same reason name() returns a cheap Arc<str> clone instead of a fresh String — see its own docs.
Source§

fn pp_log_mut(&mut self) -> &mut PpLog

Mutable access to the same field Element::pp_log reads — used by crate::pipeline::ChainBuilder to stamp the owning crate::pipeline::Pipeline’s id onto every element that passes through it, via element_pp_log. Not meant to be called from anywhere else.
Source§

fn graph_id(&self) -> Option<ElementId>

A pre-reserved graph identity for elements that expose dynamic attachment handles. Most elements receive an ID from ChainBuilder and keep the default None implementation.
Source§

impl Sink for Queue

Source§

fn consume(&mut self, buf: MediaBuffer) -> Result<()>

Source§

fn control(&mut self, msg: ControlMsg) -> Result<()>

Reacts to a ControlMsg (pause/resume/stop) and, for anything with a downstream of its own, forwards it on — same shape as consume, just a separate channel from MediaBuffer so it can reach every element (not just ones that already know how to interpret a data buffer) and, at a crate::queue::Queue, jump ahead of whatever data is backed up instead of waiting behind it. No default: every Sink has to consciously decide what this means for it, rather than silently dropping it.

Auto Trait Implementations§

§

impl !RefUnwindSafe for Queue

§

impl !UnwindSafe for Queue

§

impl Freeze for Queue

§

impl Send for Queue

§

impl Sync for Queue

§

impl Unpin for Queue

§

impl UnsafeUnpin for Queue

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
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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.

§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more