Skip to content

Commit

Permalink
Merge branch 'split_uds' of https://github.com/jean-airoldie/tokio in…
Browse files Browse the repository at this point in the history
…to split_uds_try_send
  • Loading branch information
jean-airoldie committed Dec 23, 2019
2 parents 3ce0076 + 7e4127f commit 1d8fa9e
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 6 deletions.
6 changes: 6 additions & 0 deletions tokio/src/net/unix/datagram.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::future::poll_fn;
use crate::io::PollEvented;
use super::split::{split_dgram, RecvHalf, SendHalf};

use std::convert::TryFrom;
use std::fmt;
Expand Down Expand Up @@ -270,6 +271,11 @@ impl UnixDatagram {
pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
self.io.get_ref().shutdown(how)
}

/// Splits the socket into a `RecvHalf` and `SendHalf`.
pub fn split(&mut self) -> (RecvHalf<'_>, SendHalf<'_>) {
split_dgram(self)
}
}

impl TryFrom<UnixDatagram> for mio_uds::UnixDatagram {
Expand Down
2 changes: 1 addition & 1 deletion tokio/src/net/unix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub(crate) mod listener;
pub(crate) use listener::UnixListener;

mod split;
pub use split::{ReadHalf, WriteHalf};
pub use split::{ReadHalf, WriteHalf, RecvHalf, SendHalf};

pub(crate) mod stream;
pub(crate) use stream::UnixStream;
Expand Down
60 changes: 57 additions & 3 deletions tokio/src/net/unix/split.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
//! `UnixStream` split support.
//! `UnixStream` and `UnixDatagram` split support.
//!
//! ## UnixStream
//!
//! A `UnixStream` can be split into a read half and a write half with
//! `UnixStream::split`. The read half implements `AsyncRead` while the write
Expand All @@ -7,13 +9,25 @@
//! Compared to the generic split of `AsyncRead + AsyncWrite`, this specialized
//! split has no associated overhead and enforces all invariants at the type
//! level.
//!
//! ## UnixDatagram
//!
//! A `UnixDatagram` can be split into a receive half and a send half with
//! `UnixDatagram::split`. The send half implements `send` and `send_to` and
//! the receiving one implements `recv` and `recv_from`.
//!
//! This split method has no overhead and enforces all invariants at the type
//! level.

use crate::io::{AsyncRead, AsyncWrite};
use crate::net::UnixStream;
use crate::net::{UnixDatagram, UnixStream};
use crate::future::poll_fn;

use std::io;
use std::mem::MaybeUninit;
use std::net::Shutdown;
use std::os::unix::net::SocketAddr;
use std::path::Path;
use std::pin::Pin;
use std::task::{Context, Poll};

Expand All @@ -25,10 +39,22 @@ pub struct ReadHalf<'a>(&'a UnixStream);
#[derive(Debug)]
pub struct WriteHalf<'a>(&'a UnixStream);

pub(crate) fn split(stream: &mut UnixStream) -> (ReadHalf<'_>, WriteHalf<'_>) {
/// Receiving half of a `UnixDatagram`.
#[derive(Debug)]
pub struct RecvHalf<'a>(&'a UnixDatagram);

/// Sending half of a `UnixDatagram`.
#[derive(Debug)]
pub struct SendHalf<'a>(&'a UnixDatagram);

pub(crate) fn split_stream(stream: &mut UnixStream) -> (ReadHalf<'_>, WriteHalf<'_>) {
(ReadHalf(stream), WriteHalf(stream))
}

pub(crate) fn split_dgram(dgram: &mut UnixDatagram) -> (RecvHalf<'_>, SendHalf<'_>) {
(RecvHalf(dgram), SendHalf(dgram))
}

impl AsyncRead for ReadHalf<'_> {
unsafe fn prepare_uninitialized_buffer(&self, _: &mut [MaybeUninit<u8>]) -> bool {
false
Expand Down Expand Up @@ -72,3 +98,31 @@ impl AsRef<UnixStream> for WriteHalf<'_> {
self.0
}
}

impl RecvHalf<'_> {
/// Receives a datagram from the socket.
pub async fn recv(&mut self, buf: &mut [u8]) -> io::Result<usize> {
poll_fn(|cx| self.0.poll_recv_priv(cx, buf)).await
}

/// Receives a datagram with the source address from the socket.
pub async fn recv_from(&mut self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
poll_fn(|cx| self.0.poll_recv_from_priv(cx, buf)).await
}
}

impl SendHalf<'_> {
/// Sends a datagram to the socket's peer.
pub async fn send(&mut self, buf: &[u8]) -> io::Result<usize> {
poll_fn(|cx| self.0.poll_send_priv(cx, buf)).await
}

/// Sends a datagram to the specified address.
pub async fn send_to<P>(&mut self, buf: &[u8], target: P) -> io::Result<usize>
where
P: AsRef<Path> + Unpin,
{
poll_fn(|cx| self.0.poll_send_to_priv(cx, buf, target.as_ref())).await
}
}

4 changes: 2 additions & 2 deletions tokio/src/net/unix/stream.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::future::poll_fn;
use crate::io::{AsyncRead, AsyncWrite, PollEvented};
use crate::net::unix::split::{split, ReadHalf, WriteHalf};
use crate::net::unix::split::{split_stream, ReadHalf, WriteHalf};
use crate::net::unix::ucred::{self, UCred};

use std::convert::TryFrom;
Expand Down Expand Up @@ -107,7 +107,7 @@ impl UnixStream {
/// See the module level documenation of [`split`](super::split) for more
/// details.
pub fn split(&mut self) -> (ReadHalf<'_>, WriteHalf<'_>) {
split(self)
split_stream(self)
}
}

Expand Down

0 comments on commit 1d8fa9e

Please sign in to comment.