Struct blocking::Unblock [−][src]
Runs blocking I/O on a thread pool.
Blocking I/O must be isolated from async code. This type moves blocking I/O operations onto a special thread pool while exposing a familiar async interface.
This type implements traits Stream
, AsyncRead
, AsyncWrite
, or AsyncSeek
if the
inner type implements Iterator
, Read
, Write
, or Seek
, respectively.
Caveats
Unblock
is a low-level primitive, and as such it comes with some caveats.
For higher-level primitives built on top of Unblock
, look into async-fs
or
async-process
(on Windows).
Unblock
communicates with I/O operations on the thread pool through a pipe. That means an
async read/write operation simply receives/sends some bytes from/into the pipe. When in reading
mode, the thread pool reads bytes from the I/O handle and forwards them into the pipe until it
becomes full. When in writing mode, the thread pool reads bytes from the pipe and forwards them
into the I/O handle.
Use Unblock::with_capacity()
to configure the capacity of the pipe.
Reading
If you create an Unblock
<
Stdin
>
, read some bytes from it,
and then drop it, a blocked read operation may keep hanging on the thread pool. The next
attempt to read from stdin will lose bytes read by the hanging operation. This is a difficult
problem to solve, so make sure you only use a single stdin handle for the duration of the
entire program.
Writing
If writing data through the AsyncWrite
trait, make sure to flush before dropping the
Unblock
handle or some buffered data might get lost.
Seeking
Because of buffering in the pipe, if Unblock
wraps a File
, a single
read operation may move the file cursor farther than is the span of the operation. In fact,
reading just keeps going in the background until the pipe gets full. Keep this mind when
using AsyncSeek
with relative offsets.
Examples
use blocking::Unblock; use futures_lite::prelude::*; let mut stdout = Unblock::new(std::io::stdout()); stdout.write_all(b"Hello world!").await?; stdout.flush().await?;
Implementations
impl<T> Unblock<T>
[src]
pub fn new(io: T) -> Unblock<T>
[src]
Wraps a blocking I/O handle into the async Unblock
interface.
Examples
use blocking::Unblock; let stdin = Unblock::new(std::io::stdin());
pub fn with_capacity(cap: usize, io: T) -> Unblock<T>
[src]
Wraps a blocking I/O handle into the async Unblock
interface with a custom buffer
capacity.
When communicating with the inner Stream
/Read
/Write
type from async code, data
transferred between blocking and async code goes through a buffer of limited capacity. This
constructor configures that capacity.
The default capacity is:
Examples
use blocking::Unblock; let stdout = Unblock::with_capacity(64 * 1024, std::io::stdout());
pub async fn get_mut(&mut self) -> &mut T
[src]
Gets a mutable reference to the blocking I/O handle.
This is an async method because the I/O handle might be on the thread pool and needs to be moved onto the current thread before we can get a reference to it.
Examples
use blocking::{unblock, Unblock}; use std::fs::File; let file = unblock(|| File::create("file.txt")).await?; let mut file = Unblock::new(file); let metadata = file.get_mut().await.metadata()?;
pub async fn with_mut<R, F>(&mut self, op: F) -> R where
F: FnOnce(&mut T) -> R + Send + 'static,
R: Send + 'static,
T: Send + 'static,
[src]
F: FnOnce(&mut T) -> R + Send + 'static,
R: Send + 'static,
T: Send + 'static,
Performs a blocking operation on the I/O handle.
Examples
use blocking::{unblock, Unblock}; use std::fs::File; let file = unblock(|| File::create("file.txt")).await?; let mut file = Unblock::new(file); let metadata = file.with_mut(|f| f.metadata()).await?;
pub async fn into_inner(self) -> T
[src]
Extracts the inner blocking I/O handle.
This is an async method because the I/O handle might be on the thread pool and needs to be moved onto the current thread before we can extract it.
Examples
use blocking::{unblock, Unblock}; use futures_lite::prelude::*; use std::fs::File; let file = unblock(|| File::create("file.txt")).await?; let file = Unblock::new(file); let file = file.into_inner().await;
Trait Implementations
impl<T: Read + Send + 'static> AsyncRead for Unblock<T>
[src]
fn poll_read(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut [u8]
) -> Poll<Result<usize>>
[src]
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut [u8]
) -> Poll<Result<usize>>
pub fn poll_read_vectored(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
bufs: &mut [IoSliceMut<'_>]
) -> Poll<Result<usize, Error>>
[src]
self: Pin<&mut Self>,
cx: &mut Context<'_>,
bufs: &mut [IoSliceMut<'_>]
) -> Poll<Result<usize, Error>>
impl<T: Seek + Send + 'static> AsyncSeek for Unblock<T>
[src]
impl<T: Write + Send + 'static> AsyncWrite for Unblock<T>
[src]
fn poll_write(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8]
) -> Poll<Result<usize>>
[src]
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8]
) -> Poll<Result<usize>>
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>>
[src]
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>>
[src]
pub fn poll_write_vectored(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
bufs: &[IoSlice<'_>]
) -> Poll<Result<usize, Error>>
[src]
self: Pin<&mut Self>,
cx: &mut Context<'_>,
bufs: &[IoSlice<'_>]
) -> Poll<Result<usize, Error>>
impl<T: Debug> Debug for Unblock<T>
[src]
impl<T: Iterator + Send + 'static> Stream for Unblock<T> where
T::Item: Send + 'static,
[src]
T::Item: Send + 'static,
Auto Trait Implementations
impl<T> !RefUnwindSafe for Unblock<T>
impl<T> Send for Unblock<T> where
T: Send,
T: Send,
impl<T> Sync for Unblock<T> where
T: Sync,
T: Sync,
impl<T> Unpin for Unblock<T>
impl<T> !UnwindSafe for Unblock<T>
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<R> AsyncReadExt for R where
R: AsyncRead + ?Sized,
[src]
R: AsyncRead + ?Sized,
pub fn read(&'a mut self, buf: &'a mut [u8]) -> ReadFuture<'a, Self> where
Self: Unpin,
[src]
Self: Unpin,
pub fn read_vectored(
&'a mut self,
bufs: &'a mut [IoSliceMut<'a>]
) -> ReadVectoredFuture<'a, Self> where
Self: Unpin,
[src]
&'a mut self,
bufs: &'a mut [IoSliceMut<'a>]
) -> ReadVectoredFuture<'a, Self> where
Self: Unpin,
pub fn read_to_end(
&'a mut self,
buf: &'a mut Vec<u8, Global>
) -> ReadToEndFuture<'a, Self> where
Self: Unpin,
[src]
&'a mut self,
buf: &'a mut Vec<u8, Global>
) -> ReadToEndFuture<'a, Self> where
Self: Unpin,
pub fn read_to_string(
&'a mut self,
buf: &'a mut String
) -> ReadToStringFuture<'a, Self> where
Self: Unpin,
[src]
&'a mut self,
buf: &'a mut String
) -> ReadToStringFuture<'a, Self> where
Self: Unpin,
pub fn read_exact(&'a mut self, buf: &'a mut [u8]) -> ReadExactFuture<'a, Self> where
Self: Unpin,
[src]
Self: Unpin,
pub fn take(self, limit: u64) -> Take<Self>
[src]
pub fn bytes(self) -> Bytes<Self>
[src]
pub fn chain<R>(self, next: R) -> Chain<Self, R> where
R: AsyncRead,
[src]
R: AsyncRead,
pub fn boxed_reader<'a>(self) -> Pin<Box<dyn AsyncRead + 'a + Send, Global>> where
Self: Send + 'a,
[src]
Self: Send + 'a,
impl<S> AsyncSeekExt for S where
S: AsyncSeek + ?Sized,
[src]
S: AsyncSeek + ?Sized,
pub fn seek(&mut self, pos: SeekFrom) -> SeekFuture<'_, Self> where
Self: Unpin,
[src]
Self: Unpin,
impl<W> AsyncWriteExt for W where
W: AsyncWrite + ?Sized,
[src]
W: AsyncWrite + ?Sized,
pub fn write(&'a mut self, buf: &'a [u8]) -> WriteFuture<'a, Self> where
Self: Unpin,
[src]
Self: Unpin,
pub fn write_vectored(
&'a mut self,
bufs: &'a [IoSlice<'a>]
) -> WriteVectoredFuture<'a, Self> where
Self: Unpin,
[src]
&'a mut self,
bufs: &'a [IoSlice<'a>]
) -> WriteVectoredFuture<'a, Self> where
Self: Unpin,
pub fn write_all(&'a mut self, buf: &'a [u8]) -> WriteAllFuture<'a, Self> where
Self: Unpin,
[src]
Self: Unpin,
pub fn flush(&mut self) -> FlushFuture<'_, Self> where
Self: Unpin,
[src]
Self: Unpin,
pub fn close(&mut self) -> CloseFuture<'_, Self> where
Self: Unpin,
[src]
Self: Unpin,
pub fn boxed_writer<'a>(self) -> Pin<Box<dyn AsyncWrite + 'a + Send, Global>> where
Self: Send + 'a,
[src]
Self: Send + 'a,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<S> StreamExt for S where
S: Stream + ?Sized,
[src]
S: Stream + ?Sized,
pub fn poll_next(&mut self, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> where
Self: Unpin,
[src]
Self: Unpin,
pub fn next(&mut self) -> NextFuture<'_, Self> where
Self: Unpin,
[src]
Self: Unpin,
pub fn try_next<T, E>(&mut self) -> TryNextFuture<'_, Self> where
Self: Stream<Item = Result<T, E>> + Unpin,
[src]
Self: Stream<Item = Result<T, E>> + Unpin,
pub fn count(self) -> CountFuture<Self>
[src]
pub fn map<T, F>(self, f: F) -> Map<Self, F> where
F: FnMut(Self::Item) -> T,
[src]
F: FnMut(Self::Item) -> T,
pub fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
F: FnMut(Self::Item) -> U,
U: Stream,
[src]
F: FnMut(Self::Item) -> U,
U: Stream,
pub fn flatten(self) -> Flatten<Self> where
Self::Item: Stream,
[src]
Self::Item: Stream,
pub fn then<F, Fut>(self, f: F) -> Then<Self, F, Fut> where
F: FnMut(Self::Item) -> Fut,
Fut: Future,
[src]
F: FnMut(Self::Item) -> Fut,
Fut: Future,
pub fn filter<P>(self, predicate: P) -> Filter<Self, P> where
P: FnMut(&Self::Item) -> bool,
[src]
P: FnMut(&Self::Item) -> bool,
pub fn filter_map<T, F>(self, f: F) -> FilterMap<Self, F> where
F: FnMut(Self::Item) -> Option<T>,
[src]
F: FnMut(Self::Item) -> Option<T>,
pub fn take(self, n: usize) -> Take<Self>
[src]
pub fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
P: FnMut(&Self::Item) -> bool,
[src]
P: FnMut(&Self::Item) -> bool,
pub fn skip(self, n: usize) -> Skip<Self>
[src]
pub fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
P: FnMut(&Self::Item) -> bool,
[src]
P: FnMut(&Self::Item) -> bool,
pub fn step_by(self, step: usize) -> StepBy<Self>
[src]
pub fn chain<U>(self, other: U) -> Chain<Self, U> where
U: Stream<Item = Self::Item>,
[src]
U: Stream<Item = Self::Item>,
pub fn cloned<'a, T>(self) -> Cloned<Self> where
Self: Stream<Item = &'a T>,
T: Clone + 'a,
[src]
Self: Stream<Item = &'a T>,
T: Clone + 'a,
pub fn copied<'a, T>(self) -> Copied<Self> where
Self: Stream<Item = &'a T>,
T: Copy + 'a,
[src]
Self: Stream<Item = &'a T>,
T: Copy + 'a,
pub fn collect<C>(self) -> CollectFuture<Self, C> where
C: Default + Extend<Self::Item>,
[src]
C: Default + Extend<Self::Item>,
pub fn try_collect<T, E, C>(self) -> TryCollectFuture<Self, C> where
Self: Stream<Item = Result<T, E>>,
C: Default + Extend<T>,
[src]
Self: Stream<Item = Result<T, E>>,
C: Default + Extend<T>,
pub fn partition<B, P>(self, predicate: P) -> PartitionFuture<Self, P, B> where
P: FnMut(&Self::Item) -> bool,
B: Default + Extend<Self::Item>,
[src]
P: FnMut(&Self::Item) -> bool,
B: Default + Extend<Self::Item>,
pub fn fold<T, F>(self, init: T, f: F) -> FoldFuture<Self, F, T> where
F: FnMut(T, Self::Item) -> T,
[src]
F: FnMut(T, Self::Item) -> T,
pub fn try_fold<T, E, F, B>(
&mut self,
init: B,
f: F
) -> TryFoldFuture<'_, Self, F, B> where
Self: Stream<Item = Result<T, E>> + Unpin,
F: FnMut(B, T) -> Result<B, E>,
[src]
&mut self,
init: B,
f: F
) -> TryFoldFuture<'_, Self, F, B> where
Self: Stream<Item = Result<T, E>> + Unpin,
F: FnMut(B, T) -> Result<B, E>,
pub fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
F: FnMut(&mut St, Self::Item) -> Option<B>,
[src]
F: FnMut(&mut St, Self::Item) -> Option<B>,
pub fn fuse(self) -> Fuse<Self>
[src]
pub fn cycle(self) -> Cycle<Self> where
Self: Clone,
[src]
Self: Clone,
pub fn enumerate(self) -> Enumerate<Self>
[src]
pub fn inspect<F>(self, f: F) -> Inspect<Self, F> where
F: FnMut(&Self::Item),
[src]
F: FnMut(&Self::Item),
pub fn nth(&mut self, n: usize) -> NthFuture<'_, Self> where
Self: Unpin,
[src]
Self: Unpin,
pub fn last(self) -> LastFuture<Self>
[src]
pub fn find<P>(&mut self, predicate: P) -> FindFuture<'_, Self, P> where
Self: Unpin,
P: FnMut(&Self::Item) -> bool,
[src]
Self: Unpin,
P: FnMut(&Self::Item) -> bool,
pub fn find_map<F, B>(&mut self, f: F) -> FindMapFuture<'_, Self, F> where
Self: Unpin,
F: FnMut(Self::Item) -> Option<B>,
[src]
Self: Unpin,
F: FnMut(Self::Item) -> Option<B>,
pub fn position<P>(&mut self, predicate: P) -> PositionFuture<'_, Self, P> where
Self: Unpin,
P: FnMut(Self::Item) -> bool,
[src]
Self: Unpin,
P: FnMut(Self::Item) -> bool,
pub fn all<P>(&mut self, predicate: P) -> AllFuture<'_, Self, P> where
Self: Unpin,
P: FnMut(Self::Item) -> bool,
[src]
Self: Unpin,
P: FnMut(Self::Item) -> bool,
pub fn any<P>(&mut self, predicate: P) -> AnyFuture<'_, Self, P> where
Self: Unpin,
P: FnMut(Self::Item) -> bool,
[src]
Self: Unpin,
P: FnMut(Self::Item) -> bool,
pub fn for_each<F>(self, f: F) -> ForEachFuture<Self, F> where
F: FnMut(Self::Item),
[src]
F: FnMut(Self::Item),
pub fn try_for_each<F, E>(&mut self, f: F) -> TryForEachFuture<'_, Self, F> where
Self: Unpin,
F: FnMut(Self::Item) -> Result<(), E>,
[src]
Self: Unpin,
F: FnMut(Self::Item) -> Result<(), E>,
pub fn zip<U>(self, other: U) -> Zip<Self, U> where
U: Stream,
[src]
U: Stream,
pub fn unzip<A, B, FromA, FromB>(self) -> UnzipFuture<Self, FromA, FromB> where
Self: Stream<Item = (A, B)>,
FromA: Default + Extend<A>,
FromB: Default + Extend<B>,
[src]
Self: Stream<Item = (A, B)>,
FromA: Default + Extend<A>,
FromB: Default + Extend<B>,
pub fn or<S>(self, other: S) -> Or<Self, S> where
S: Stream<Item = Self::Item>,
[src]
S: Stream<Item = Self::Item>,
pub fn race<S>(self, other: S) -> Race<Self, S> where
S: Stream<Item = Self::Item>,
[src]
S: Stream<Item = Self::Item>,
pub fn boxed<'a>(
self
) -> Pin<Box<dyn Stream<Item = Self::Item> + 'a + Send, Global>> where
Self: Send + 'a,
[src]
self
) -> Pin<Box<dyn Stream<Item = Self::Item> + 'a + Send, Global>> where
Self: Send + 'a,
pub fn boxed_local<'a>(
self
) -> Pin<Box<dyn Stream<Item = Self::Item> + 'a, Global>> where
Self: 'a,
[src]
self
) -> Pin<Box<dyn Stream<Item = Self::Item> + 'a, Global>> where
Self: 'a,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
pub fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<S, T, E> TryStream for S where
S: Stream<Item = Result<T, E>> + ?Sized,
[src]
S: Stream<Item = Result<T, E>> + ?Sized,