Skip to main content

IoContext

Struct IoContext 

Source
pub struct IoContext(/* private fields */);
Expand description

Connection context shared with transport read and write tasks.

Transport implementations obtain buffers from this context, perform nonblocking I/O, and return completion through release_read_buf and update_write_status. Their return value tells the task whether to continue, pause until notified, or stop.

§Shutdown

A transport task runs until poll_read_ready or poll_write_ready reports Readiness::Close or Readiness::Terminate, or until a status update returns IoTaskStatus::Stop. All of those imply that the connection is already closing or closed.

Graceful shutdown runs in two phases. In the first the filters shut down while both directions stay open. In the second, buffered output is drained into the transport while the read side is paused; Readiness::Close is reported only once nothing is left to write. A single shutdown timeout bounds both phases. If it elapses during filter shutdown, that phase is skipped and transport shutdown begins. If it elapses during transport shutdown, the connection closes and any remaining output is discarded.

So by the time the loop exits there is nothing left to drain, whether the connection was shut down gracefully or terminated. A task must never attempt a final flush on the way out; it should release the transport immediately and report the outcome through stopped. The two variants differ only in how the transport is released: Readiness::Close closes both directions gracefully, while Readiness::Terminate skips the graceful close so that an aborted connection stays distinguishable from one that ended normally. Terminate is reported for an explicit IoRef::terminate, and when Io is dropped while output it accepted has not reached the transport, because the filter chain goes away with it and that output can never be delivered. Every other way a connection can end, an expired shutdown timeout included, reports Close.

Implementations§

Source§

impl IoContext

Source

pub fn id(&self) -> Id

Gets the ID.

Source

pub fn tag(&self) -> &'static str

Gets the I/O tag.

Source

pub fn shutdown_timeout(&self) -> Seconds

Gets the configured shutdown timeout.

A backend whose own teardown can stall, such as one waiting for cancelled operations to complete, can bound it with this, as the graceful shutdown before it is bounded.

Source

pub fn poll_read_ready(&self, cx: &mut Context<'_>) -> Poll<Readiness>

Checks readiness for read operations.

Resolves to Readiness::Ready, Readiness::Close or Readiness::Terminate, or stays Pending. Reads continue through the filter shutdown phase so that filters can complete theirs, and are paused for the transport shutdown phase, so Close is resolved here only once the connection is terminated.

A filter that is not ready while the io state allows reads pauses them, see IoRef::is_read_filter_paused. The dispatcher is notified when the pause starts and when it ends.

Source

pub fn poll_write_ready(&self, cx: &mut Context<'_>) -> Poll<Readiness>

Checks readiness for write operations.

Resolves to Readiness::Ready, Readiness::Close or Readiness::Terminate, or stays Pending. Unlike the read path this reports Close at the end of a graceful shutdown as well, once buffered output has been drained, so the task must not flush again.

A filter that is not ready while output is waiting pauses writes, see IoRef::is_write_filter_paused. The dispatcher is notified when the pause starts and when it ends.

Source

pub fn stop(&self, e: Option<Error>)

Stops I/O processing without graceful filter shutdown.

Pending application work is not drained. Unlike IoRef::terminate, this does not request an aborted transport release: the transport observes Readiness::Close and closes both directions gracefully. Call stopped afterwards, once transport teardown has actually finished.

Source

pub fn stopped(&self, e: Option<Error>)

Marks backend transport teardown as complete.

Source

pub fn take_read_buf(&self) -> BytesMut ⓘ

Takes a buffer for the next transport read.

The returned buffer must be released exactly once through release_read_buf, even when the read fails or would otherwise stop the task.

This hands out a buffer of its own while the dispatcher still has input to consume, because the read buffer is moved out of the io state until it is released and the dispatcher would not find it. A transport whose read completes without suspending can avoid that with with_read_buf.

Source

pub fn release_read_buf( &self, buf: BytesMut, status: Poll<Result<usize, Error>>, ) -> IoTaskStatus

Releases a transport read buffer and reports the read result.

This is the counterpart of take_read_buf; every buffer it hands out must come back here exactly once.

Poll::Ready(Ok(n)) reports that n bytes were appended to buf. Zero marks the transport read side as closed and invokes the read filter chain once with no new bytes. This lets filters emit final buffered data or report truncated input. Further transport reads are parked, but buffered input remains decodable and the write side remains usable until graceful shutdown. Poll::Ready(Err(_)) terminates the connection. Poll::Pending returns the buffer after a nonblocking operation made no progress or a submitted operation was canceled for reissue.

The returned IoTaskStatus instructs the read task to continue immediately, pause until notified, or stop.

Source

pub fn with_read_buf<F>(&self, f: F) -> IoTaskStatus
where F: FnOnce(&mut BytesMut) -> Poll<Result<usize, Error>>,

Reads into the read buffer in place and reports the read result.

This is the counterpart of take_read_buf and release_read_buf for a transport whose read completes without suspending. f reads into the buffer it is given and reports the same status release_read_buf takes, with the same meaning.

The buffer is not moved out of the io state for the duration of the call, so no temporary buffer is taken from the pool and no append is needed to put the result back. A transport that keeps the buffer across a suspension point cannot use this: the buffer would be missing while the dispatcher looks for input, so it must take one of its own through take_read_buf instead.

f must not read from this io again. Nested read access is unsupported and may terminate the connection or lose nested buffer changes.

Source

pub fn with_write_dst<F, R>(&self, f: F) -> R
where F: FnOnce(&mut BytePages) -> R,

Provides mutable access to the transport-facing write destination.

This holds the encoded bytes that are ready to be written out.

Pending filter output is processed before f is invoked. The transport may write bytes out directly, or take ownership of pages and write them later; any page it removes is counted as in-flight output until it is either returned to this buffer or reported as written through update_write_status.

§Panics

Panics if the closure accesses the transport-facing write buffer again.

Source

pub fn update_write_status(&self, status: Result<usize, Error>) -> IoTaskStatus

Updates the write status.

Ok(n) reports that the write attempt completed without error and that n bytes reached the peer; n is zero when the attempt moved nothing. Any page the transport is still holding stays counted as outstanding output, so it must either be returned to the write buffer or reported here. An error terminates the connection. The returned IoTaskStatus instructs the write task to continue, pause until notified, or stop.

Trait Implementations§

Source§

impl Clone for IoContext

Source§

fn clone(&self) -> IoContext

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for IoContext

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.