udp: UdpSocket split support (#1226)

This commit is contained in:
Yin Guanhao
2019-07-08 14:47:31 -07:00
committed by Carl Lerche
parent 8b49a1e05f
commit 88e775dcf0
9 changed files with 247 additions and 13 deletions
+54
View File
@@ -1,3 +1,4 @@
use super::split::{split, UdpSocketRecvHalf, UdpSocketSendHalf};
use super::{Recv, RecvFrom, Send, SendTo};
use mio;
use std::convert::TryFrom;
@@ -42,6 +43,16 @@ impl UdpSocket {
Ok(UdpSocket { io })
}
/// Split the `UdpSocket` into a receive half and a send half. The two parts
/// can be used to receive and send datagrams concurrently, even from two
/// different tasks.
///
/// See the module level documenation of [`split`](super::split) for more
/// details.
pub fn split(self) -> (UdpSocketRecvHalf, UdpSocketSendHalf) {
split(self)
}
/// Returns the local address that this socket is bound to.
pub fn local_addr(&self) -> io::Result<SocketAddr> {
self.io.get_ref().local_addr()
@@ -83,6 +94,24 @@ impl UdpSocket {
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<io::Result<usize>> {
self.poll_send_priv(cx, buf)
}
// Poll IO functions that takes `&self` are provided for the split API.
//
// They are not public because (taken from the doc of `PollEvented`):
//
// While `PollEvented` is `Sync` (if the underlying I/O type is `Sync`), the
// caller must ensure that there are at most two tasks that use a
// `PollEvented` instance concurrently. One for reading and one for writing.
// While violating this requirement is "safe" from a Rust memory model point
// of view, it will result in unexpected behavior in the form of lost
// notifications and tasks hanging.
pub(crate) fn poll_send_priv(
&self,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<io::Result<usize>> {
ready!(self.io.poll_write_ready(cx))?;
@@ -134,6 +163,14 @@ impl UdpSocket {
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<io::Result<usize>> {
self.poll_recv_priv(cx, buf)
}
pub(crate) fn poll_recv_priv(
&self,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<io::Result<usize>> {
ready!(self.io.poll_read_ready(cx, mio::Ready::readable()))?;
@@ -173,6 +210,15 @@ impl UdpSocket {
cx: &mut Context<'_>,
buf: &[u8],
target: &SocketAddr,
) -> Poll<io::Result<usize>> {
self.poll_send_to_priv(cx, buf, target)
}
pub(crate) fn poll_send_to_priv(
&self,
cx: &mut Context<'_>,
buf: &[u8],
target: &SocketAddr,
) -> Poll<io::Result<usize>> {
ready!(self.io.poll_write_ready(cx))?;
@@ -201,6 +247,14 @@ impl UdpSocket {
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<Result<(usize, SocketAddr), io::Error>> {
self.poll_recv_from_priv(cx, buf)
}
pub(crate) fn poll_recv_from_priv(
&self,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<Result<(usize, SocketAddr), io::Error>> {
ready!(self.io.poll_read_ready(cx, mio::Ready::readable()))?;