compio_fs::pipe

Struct Sender

Source
pub struct Sender { /* private fields */ }
Available on Unix only.
Expand description

Writing end of a Unix pipe.

It can be constructed from a FIFO file with OpenOptions::open_sender.

Opening a named pipe for writing involves a few steps. Call to OpenOptions::open_sender might fail with an error indicating different things:

  • io::ErrorKind::NotFound - There is no file at the specified path.
  • io::ErrorKind::InvalidInput - The file exists, but it is not a FIFO.
  • ENXIO - The file is a FIFO, but no process has it open for reading. Sleep for a while and try again.
  • Other OS errors not specific to opening FIFO files.

Opening a Sender from a FIFO file should look like this:

use std::time::Duration;

use compio_fs::pipe;
use compio_runtime::time;

const FIFO_NAME: &str = "path/to/a/fifo";

// Wait for a reader to open the file.
let tx = loop {
    match pipe::OpenOptions::new().open_sender(FIFO_NAME).await {
        Ok(tx) => break tx,
        Err(e) if e.raw_os_error() == Some(libc::ENXIO) => {}
        Err(e) => return Err(e.into()),
    }

    time::sleep(Duration::from_millis(50)).await;
};

On Linux, it is possible to create a Sender without waiting in a sleeping loop. This is done by opening a named pipe in read-write access mode with OpenOptions::read_write. This way, a Sender can at the same time hold both a writing end and a reading end, and the latter allows to open a FIFO without ENXIO error since the pipe is open for reading as well.

Sender cannot be used to read from a pipe, so in practice the read access is only used when a FIFO is opened. However, using a Sender in read-write mode may lead to lost data, because written data will be dropped by the system as soon as all pipe ends are closed. To avoid lost data you have to make sure that a reading end has been opened before dropping a Sender.

Note that using read-write access mode with FIFO files is not defined by the POSIX standard and it is only guaranteed to work on Linux.

use compio_fs::pipe;
use compio_io::AsyncWriteExt;

const FIFO_NAME: &str = "path/to/a/fifo";

let mut tx = pipe::OpenOptions::new()
    .read_write(true)
    .open_sender(FIFO_NAME)
    .unwrap();

// Asynchronously write to the pipe before a reader.
tx.write_all("hello world").await.unwrap();

Implementations§

Source§

impl Sender

Source

pub fn close(self) -> impl Future<Output = Result<()>>

Close the pipe. If the returned future is dropped before polling, the pipe won’t be closed.

Trait Implementations§

Source§

impl AsRawFd for Sender

Source§

fn as_raw_fd(&self) -> RawFd

Extracts the raw file descriptor. Read more
Source§

impl AsyncWrite for &Sender

Source§

async fn write<T: IoBuf>(&mut self, buffer: T) -> BufResult<usize, T>

Write some bytes from the buffer into this source and return a BufResult, consisting of the buffer and a usize indicating how many bytes were written.
Source§

async fn write_vectored<T: IoVectoredBuf>( &mut self, buffer: T, ) -> BufResult<usize, T>

Like write, except that it write bytes from a buffer implements IoVectoredBuf into the source. Read more
Source§

async fn flush(&mut self) -> Result<()>

Attempts to flush the object, ensuring that any buffered data reach their destination.
Source§

async fn shutdown(&mut self) -> Result<()>

Initiates or attempts to shut down this writer, returning success when the I/O connection has completely shut down.
Source§

impl AsyncWrite for Sender

Source§

async fn write<T: IoBuf>(&mut self, buf: T) -> BufResult<usize, T>

Write some bytes from the buffer into this source and return a BufResult, consisting of the buffer and a usize indicating how many bytes were written.
Source§

async fn write_vectored<T: IoVectoredBuf>( &mut self, buf: T, ) -> BufResult<usize, T>

Like write, except that it write bytes from a buffer implements IoVectoredBuf into the source. Read more
Source§

async fn flush(&mut self) -> Result<()>

Attempts to flush the object, ensuring that any buffered data reach their destination.
Source§

async fn shutdown(&mut self) -> Result<()>

Initiates or attempts to shut down this writer, returning success when the I/O connection has completely shut down.
Source§

impl Clone for Sender

Source§

fn clone(&self) -> Sender

Returns a copy of the value. Read more
1.0.0 · Source§

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

Performs copy-assignment from source. Read more
Source§

impl Debug for Sender

Source§

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

Formats the value using the given formatter. Read more
Source§

impl FromRawFd for Sender

Source§

unsafe fn from_raw_fd(fd: RawFd) -> Self

Constructs a new instance of Self from the given raw file descriptor. Read more
Source§

impl ToSharedFd<File> for Sender

Source§

fn to_shared_fd(&self) -> SharedFd<File>

Return a cloned SharedFd.

Auto Trait Implementations§

§

impl Freeze for Sender

§

impl RefUnwindSafe for Sender

§

impl Send for Sender

§

impl Sync for Sender

§

impl Unpin for Sender

§

impl UnwindSafe for Sender

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<A> AsyncWriteExt for A
where A: AsyncWrite + ?Sized,

Source§

fn by_ref(&mut self) -> &mut Self
where Self: Sized,

Creates a “by reference” adaptor for this instance of AsyncWrite. Read more
Source§

async fn write_all<T>(&mut self, buf: T) -> BufResult<(), T>
where T: IoBuf,

Write the entire contents of a buffer into this writer.
Source§

async fn write_vectored_all<T>(&mut self, buf: T) -> BufResult<(), T>
where T: IoVectoredBuf,

Write the entire contents of a buffer into this writer. Like AsyncWrite::write_vectored, except that it tries to write the entire contents of the buffer into this writer.
Source§

async fn write_u8(&mut self, num: u8) -> Result<(), Error>

Write a big endian u8 into the underlying writer.
Source§

async fn write_u8_le(&mut self, num: u8) -> Result<(), Error>

Write a little endian u8 into the underlying writer.
Source§

async fn write_u16(&mut self, num: u16) -> Result<(), Error>

Write a big endian u16 into the underlying writer.
Source§

async fn write_u16_le(&mut self, num: u16) -> Result<(), Error>

Write a little endian u16 into the underlying writer.
Source§

async fn write_u32(&mut self, num: u32) -> Result<(), Error>

Write a big endian u32 into the underlying writer.
Source§

async fn write_u32_le(&mut self, num: u32) -> Result<(), Error>

Write a little endian u32 into the underlying writer.
Source§

async fn write_u64(&mut self, num: u64) -> Result<(), Error>

Write a big endian u64 into the underlying writer.
Source§

async fn write_u64_le(&mut self, num: u64) -> Result<(), Error>

Write a little endian u64 into the underlying writer.
Source§

async fn write_u128(&mut self, num: u128) -> Result<(), Error>

Write a big endian u128 into the underlying writer.
Source§

async fn write_u128_le(&mut self, num: u128) -> Result<(), Error>

Write a little endian u128 into the underlying writer.
Source§

async fn write_i8(&mut self, num: i8) -> Result<(), Error>

Write a big endian i8 into the underlying writer.
Source§

async fn write_i8_le(&mut self, num: i8) -> Result<(), Error>

Write a little endian i8 into the underlying writer.
Source§

async fn write_i16(&mut self, num: i16) -> Result<(), Error>

Write a big endian i16 into the underlying writer.
Source§

async fn write_i16_le(&mut self, num: i16) -> Result<(), Error>

Write a little endian i16 into the underlying writer.
Source§

async fn write_i32(&mut self, num: i32) -> Result<(), Error>

Write a big endian i32 into the underlying writer.
Source§

async fn write_i32_le(&mut self, num: i32) -> Result<(), Error>

Write a little endian i32 into the underlying writer.
Source§

async fn write_i64(&mut self, num: i64) -> Result<(), Error>

Write a big endian i64 into the underlying writer.
Source§

async fn write_i64_le(&mut self, num: i64) -> Result<(), Error>

Write a little endian i64 into the underlying writer.
Source§

async fn write_i128(&mut self, num: i128) -> Result<(), Error>

Write a big endian i128 into the underlying writer.
Source§

async fn write_i128_le(&mut self, num: i128) -> Result<(), Error>

Write a little endian i128 into the underlying writer.
Source§

async fn write_f32(&mut self, num: f32) -> Result<(), Error>

Write a big endian f32 into the underlying writer.
Source§

async fn write_f32_le(&mut self, num: f32) -> Result<(), Error>

Write a little endian f32 into the underlying writer.
Source§

async fn write_f64(&mut self, num: f64) -> Result<(), Error>

Write a big endian f64 into the underlying writer.
Source§

async fn write_f64_le(&mut self, num: f64) -> Result<(), Error>

Write a little endian f64 into the underlying writer.
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, dst: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

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

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

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.

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.
Source§

impl<T> WithSubscriber for T

Source§

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
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

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