forked from M-Labs/artiq
parent
52e331204e
commit
89b7c9e091
|
@ -158,7 +158,7 @@ dependencies = [
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"logger_artiq 0.0.0",
|
"logger_artiq 0.0.0",
|
||||||
"proto 0.0.0",
|
"proto 0.0.0",
|
||||||
"smoltcp 0.4.0 (git+https://github.com/m-labs/smoltcp?rev=6f5ae33)",
|
"smoltcp 0.4.0 (git+https://github.com/m-labs/smoltcp?rev=f64a99a)",
|
||||||
"std_artiq 0.0.0",
|
"std_artiq 0.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -184,7 +184,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smoltcp"
|
name = "smoltcp"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "git+https://github.com/m-labs/smoltcp?rev=6f5ae33#6f5ae33501827d57926469c6f1a860205a24f7ae"
|
source = "git+https://github.com/m-labs/smoltcp?rev=f64a99a#f64a99a4e6d744c3a6f3d9a54a0fb3f94e4b0ec8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -222,7 +222,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum log_buffer 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ec57723b84bbe7bdf76aa93169c9b59e67473317c6de3a83cb2a0f8ccb2aa493"
|
"checksum log_buffer 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ec57723b84bbe7bdf76aa93169c9b59e67473317c6de3a83cb2a0f8ccb2aa493"
|
||||||
"checksum managed 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b5d48e8c30a4363e2981fe4db20527f6ab0f32a243bbc75379dea5a64f60dae4"
|
"checksum managed 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b5d48e8c30a4363e2981fe4db20527f6ab0f32a243bbc75379dea5a64f60dae4"
|
||||||
"checksum rustc-cfg 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "56a596b5718bf5e059d59a30af12f7f462a152de147aa462b70892849ee18704"
|
"checksum rustc-cfg 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "56a596b5718bf5e059d59a30af12f7f462a152de147aa462b70892849ee18704"
|
||||||
"checksum smoltcp 0.4.0 (git+https://github.com/m-labs/smoltcp?rev=6f5ae33)" = "<none>"
|
"checksum smoltcp 0.4.0 (git+https://github.com/m-labs/smoltcp?rev=f64a99a)" = "<none>"
|
||||||
"checksum walkdir 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "dd7c16466ecc507c7cb5988db03e6eab4aaeab89a5c37a29251fcfd3ac9b7afe"
|
"checksum walkdir 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "dd7c16466ecc507c7cb5988db03e6eab4aaeab89a5c37a29251fcfd3ac9b7afe"
|
||||||
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
||||||
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
||||||
|
|
|
@ -37,6 +37,6 @@ features = ["alloc"]
|
||||||
|
|
||||||
[dependencies.smoltcp]
|
[dependencies.smoltcp]
|
||||||
git = "https://github.com/m-labs/smoltcp"
|
git = "https://github.com/m-labs/smoltcp"
|
||||||
rev = "6f5ae33"
|
rev = "f64a99a"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["alloc", "log"]
|
features = ["alloc", "log", "proto-udp", "proto-tcp"]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use core::slice;
|
use core::slice;
|
||||||
use board::{csr, mem};
|
use board::{csr, mem};
|
||||||
use smoltcp::Error;
|
use smoltcp::Error;
|
||||||
use smoltcp::phy::{DeviceLimits, Device};
|
use smoltcp::phy::{DeviceCapabilities, Device};
|
||||||
|
|
||||||
const RX0_BASE: usize = mem::ETHMAC_BASE + 0x0000;
|
const RX0_BASE: usize = mem::ETHMAC_BASE + 0x0000;
|
||||||
const RX1_BASE: usize = mem::ETHMAC_BASE + 0x0800;
|
const RX1_BASE: usize = mem::ETHMAC_BASE + 0x0800;
|
||||||
|
@ -23,11 +23,11 @@ impl Device for EthernetDevice {
|
||||||
type RxBuffer = RxBuffer;
|
type RxBuffer = RxBuffer;
|
||||||
type TxBuffer = TxBuffer;
|
type TxBuffer = TxBuffer;
|
||||||
|
|
||||||
fn limits(&self) -> DeviceLimits {
|
fn capabilities(&self) -> DeviceCapabilities {
|
||||||
let mut limits = DeviceLimits::default();
|
let mut caps = DeviceCapabilities::default();
|
||||||
limits.max_transmission_unit = 1514;
|
caps.max_transmission_unit = 1514;
|
||||||
limits.max_burst_size = Some(RX_BUFFERS.len());
|
caps.max_burst_size = Some(RX_BUFFERS.len());
|
||||||
limits
|
caps
|
||||||
}
|
}
|
||||||
|
|
||||||
fn receive(&mut self, _timestamp: u64) -> Result<Self::RxBuffer, Error> {
|
fn receive(&mut self, _timestamp: u64) -> Result<Self::RxBuffer, Error> {
|
||||||
|
|
|
@ -22,7 +22,7 @@ extern crate amp;
|
||||||
extern crate drtioaux;
|
extern crate drtioaux;
|
||||||
|
|
||||||
use std::boxed::Box;
|
use std::boxed::Box;
|
||||||
use smoltcp::wire::{EthernetAddress, IpAddress};
|
use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr};
|
||||||
use proto::{mgmt_proto, analyzer_proto, moninj_proto, rpc_proto, session_proto, kernel_proto};
|
use proto::{mgmt_proto, analyzer_proto, moninj_proto, rpc_proto, session_proto, kernel_proto};
|
||||||
use amp::{mailbox, rpc_queue};
|
use amp::{mailbox, rpc_queue};
|
||||||
|
|
||||||
|
@ -93,15 +93,15 @@ fn startup() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let protocol_addr;
|
let protocol_cidr;
|
||||||
match config::read_str("ip", |r| r?.parse()) {
|
match config::read_str("ip", |r| r?.parse()) {
|
||||||
Err(()) | Ok(IpAddress::Unspecified) => {
|
Err(()) => {
|
||||||
protocol_addr = IpAddress::v4(192, 168, 1, 50);
|
protocol_cidr = IpCidr::new(IpAddress::v4(192, 168, 1, 50), 24);
|
||||||
info!("using default IP address {}", protocol_addr);
|
info!("using default IP address {}", protocol_cidr);
|
||||||
}
|
}
|
||||||
Ok(addr) => {
|
Ok(cidr) => {
|
||||||
protocol_addr = addr;
|
protocol_cidr = cidr;
|
||||||
info!("using IP address {}", protocol_addr);
|
info!("using IP address {}", protocol_cidr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ fn startup() {
|
||||||
let arp_cache = smoltcp::iface::SliceArpCache::new([Default::default(); 8]);
|
let arp_cache = smoltcp::iface::SliceArpCache::new([Default::default(); 8]);
|
||||||
let mut interface = smoltcp::iface::EthernetInterface::new(
|
let mut interface = smoltcp::iface::EthernetInterface::new(
|
||||||
Box::new(net_device), Box::new(arp_cache) as Box<smoltcp::iface::ArpCache>,
|
Box::new(net_device), Box::new(arp_cache) as Box<smoltcp::iface::ArpCache>,
|
||||||
hardware_addr, [protocol_addr]);
|
hardware_addr, [protocol_cidr], None);
|
||||||
|
|
||||||
let mut scheduler = sched::Scheduler::new();
|
let mut scheduler = sched::Scheduler::new();
|
||||||
let io = scheduler.io();
|
let io = scheduler.io();
|
||||||
|
|
|
@ -1,19 +1,20 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::cell::{Cell, RefCell, RefMut};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
use std::io::{Read, Write, Result, Error, ErrorKind};
|
use std::io::{Read, Write, Result, Error, ErrorKind};
|
||||||
use fringe::OwnedStack;
|
use fringe::OwnedStack;
|
||||||
use fringe::generator::{Generator, Yielder, State as GeneratorState};
|
use fringe::generator::{Generator, Yielder, State as GeneratorState};
|
||||||
|
|
||||||
use smoltcp::wire::IpEndpoint;
|
use smoltcp::wire::IpEndpoint;
|
||||||
use smoltcp::socket::{AsSocket, SocketHandle};
|
use smoltcp::socket::{SocketHandle, SocketRef};
|
||||||
type SocketSet = ::smoltcp::socket::SocketSet<'static, 'static, 'static>;
|
|
||||||
|
|
||||||
use board;
|
use board;
|
||||||
use urc::Urc;
|
use urc::Urc;
|
||||||
|
|
||||||
|
type SocketSet = ::smoltcp::socket::SocketSet<'static, 'static, 'static>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct WaitRequest {
|
struct WaitRequest {
|
||||||
event: Option<*const (Fn() -> bool + 'static)>,
|
event: Option<*const (Fn() -> bool + 'static)>,
|
||||||
|
@ -241,12 +242,13 @@ macro_rules! until {
|
||||||
let (sockets, handle) = ($socket.io.sockets.clone(), $socket.handle);
|
let (sockets, handle) = ($socket.io.sockets.clone(), $socket.handle);
|
||||||
$socket.io.until(move || {
|
$socket.io.until(move || {
|
||||||
let mut sockets = borrow_mut!(sockets);
|
let mut sockets = borrow_mut!(sockets);
|
||||||
let $var: &mut $ty = sockets.get_mut(handle).as_socket();
|
let $var = sockets.get::<$ty>(handle);
|
||||||
$cond
|
$cond
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
use ::smoltcp::Error as ErrorLower;
|
use ::smoltcp::Error as ErrorLower;
|
||||||
// https://github.com/rust-lang/rust/issues/44057
|
// https://github.com/rust-lang/rust/issues/44057
|
||||||
// type ErrorLower = ::smoltcp::Error;
|
// type ErrorLower = ::smoltcp::Error;
|
||||||
|
@ -278,40 +280,44 @@ impl<'a> UdpSocket<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_lower<'b>(&'b self) -> RefMut<'b, UdpSocketLower> {
|
fn with_lower<F, R>(&self, f: F) -> R
|
||||||
RefMut::map(borrow_mut!(self.io.sockets),
|
where F: FnOnce(SocketRef<UdpSocketLower>) -> R {
|
||||||
|sockets| sockets.get_mut(self.handle).as_socket())
|
let mut sockets = borrow_mut!(self.io.sockets);
|
||||||
|
let result = f(sockets.get(self.handle));
|
||||||
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bind<T: Into<IpEndpoint>>(&self, endpoint: T) -> Result<()> {
|
pub fn bind<T: Into<IpEndpoint>>(&self, endpoint: T) -> Result<()> {
|
||||||
match self.as_lower().bind(endpoint) {
|
self.with_lower(|mut s| s.bind(endpoint))
|
||||||
Ok(()) => Ok(()),
|
.map_err(|err| {
|
||||||
Err(ErrorLower::Illegal) =>
|
match err {
|
||||||
Err(Error::new(ErrorKind::Other, "already listening")),
|
ErrorLower::Illegal =>
|
||||||
Err(ErrorLower::Unaddressable) =>
|
Error::new(ErrorKind::Other, "already listening"),
|
||||||
Err(Error::new(ErrorKind::AddrNotAvailable, "port cannot be zero")),
|
ErrorLower::Unaddressable =>
|
||||||
|
Error::new(ErrorKind::AddrNotAvailable, "port cannot be zero"),
|
||||||
_ => unreachable!()
|
_ => unreachable!()
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn recv_from(&self, buf: &mut [u8]) -> Result<(usize, IpEndpoint)> {
|
pub fn recv_from(&self, buf: &mut [u8]) -> Result<(usize, IpEndpoint)> {
|
||||||
until!(self, UdpSocketLower, |s| s.can_recv())?;
|
until!(self, UdpSocketLower, |s| s.can_recv())?;
|
||||||
match self.as_lower().recv_slice(buf) {
|
self.with_lower(|mut s| s.recv_slice(buf))
|
||||||
Ok(result) => Ok(result),
|
.map_err(|_| unreachable!())
|
||||||
Err(_) => unreachable!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_to(&self, buf: &[u8], addr: IpEndpoint) -> Result<()> {
|
pub fn send_to(&self, buf: &[u8], addr: IpEndpoint) -> Result<()> {
|
||||||
until!(self, UdpSocketLower, |s| s.can_send())?;
|
until!(self, UdpSocketLower, |s| s.can_send())?;
|
||||||
match self.as_lower().send_slice(buf, addr) {
|
self.with_lower(|mut s| s.send_slice(buf, addr))
|
||||||
Ok(()) => Ok(()),
|
.map_err(|err| {
|
||||||
Err(ErrorLower::Unaddressable) =>
|
match err {
|
||||||
Err(Error::new(ErrorKind::AddrNotAvailable, "unaddressable destination")),
|
ErrorLower::Unaddressable =>
|
||||||
Err(ErrorLower::Truncated) =>
|
Error::new(ErrorKind::AddrNotAvailable, "unaddressable destination"),
|
||||||
Err(Error::new(ErrorKind::Other, "packet does not fit in buffer")),
|
ErrorLower::Truncated =>
|
||||||
Err(_) => unreachable!()
|
Error::new(ErrorKind::Other, "packet does not fit in buffer"),
|
||||||
|
_ => unreachable!()
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,35 +358,41 @@ impl<'a> TcpListener<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_lower<'b>(&'b self) -> RefMut<'b, TcpSocketLower> {
|
fn with_lower<F, R>(&self, f: F) -> R
|
||||||
RefMut::map(borrow_mut!(self.io.sockets),
|
where F: FnOnce(SocketRef<TcpSocketLower>) -> R {
|
||||||
|sockets| sockets.get_mut(self.handle.get()).as_socket())
|
let mut sockets = borrow_mut!(self.io.sockets);
|
||||||
|
let result = f(sockets.get(self.handle.get()));
|
||||||
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_open(&self) -> bool {
|
pub fn is_open(&self) -> bool {
|
||||||
self.as_lower().is_open()
|
self.with_lower(|s| s.is_open())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn can_accept(&self) -> bool {
|
pub fn can_accept(&self) -> bool {
|
||||||
self.as_lower().is_active()
|
self.with_lower(|s| s.is_active())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn local_endpoint(&self) -> IpEndpoint {
|
pub fn local_endpoint(&self) -> IpEndpoint {
|
||||||
self.as_lower().local_endpoint()
|
self.with_lower(|s| s.local_endpoint())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn listen<T: Into<IpEndpoint>>(&self, endpoint: T) -> Result<()> {
|
pub fn listen<T: Into<IpEndpoint>>(&self, endpoint: T) -> Result<()> {
|
||||||
let endpoint = endpoint.into();
|
let endpoint = endpoint.into();
|
||||||
match self.as_lower().listen(endpoint) {
|
self.with_lower(|mut s| s.listen(endpoint))
|
||||||
Ok(()) => Ok(()),
|
.map(|()| {
|
||||||
Err(ErrorLower::Illegal) =>
|
|
||||||
Err(Error::new(ErrorKind::Other, "already listening")),
|
|
||||||
Err(ErrorLower::Unaddressable) =>
|
|
||||||
Err(Error::new(ErrorKind::InvalidInput, "port cannot be zero")),
|
|
||||||
_ => unreachable!()
|
|
||||||
}?;
|
|
||||||
self.endpoint.set(endpoint);
|
self.endpoint.set(endpoint);
|
||||||
Ok(())
|
()
|
||||||
|
})
|
||||||
|
.map_err(|err| {
|
||||||
|
match err {
|
||||||
|
ErrorLower::Illegal =>
|
||||||
|
Error::new(ErrorKind::Other, "already listening"),
|
||||||
|
ErrorLower::Unaddressable =>
|
||||||
|
Error::new(ErrorKind::InvalidInput, "port cannot be zero"),
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn accept(&self) -> Result<TcpStream<'a>> {
|
pub fn accept(&self) -> Result<TcpStream<'a>> {
|
||||||
|
@ -390,7 +402,7 @@ impl<'a> TcpListener<'a> {
|
||||||
let (sockets, handle) = (self.io.sockets.clone(), self.handle.get());
|
let (sockets, handle) = (self.io.sockets.clone(), self.handle.get());
|
||||||
self.io.until(move || {
|
self.io.until(move || {
|
||||||
let mut sockets = borrow_mut!(sockets);
|
let mut sockets = borrow_mut!(sockets);
|
||||||
let socket: &mut TcpSocketLower = sockets.get_mut(handle).as_socket();
|
let socket = sockets.get::<TcpSocketLower>(handle);
|
||||||
socket.may_send() || socket.may_recv()
|
socket.may_send() || socket.may_recv()
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -407,13 +419,13 @@ impl<'a> TcpListener<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn close(&self) {
|
pub fn close(&self) {
|
||||||
self.as_lower().close()
|
self.with_lower(|mut s| s.close())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Drop for TcpListener<'a> {
|
impl<'a> Drop for TcpListener<'a> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.as_lower().close();
|
self.with_lower(|mut s| s.close());
|
||||||
borrow_mut!(self.io.sockets).release(self.handle.get())
|
borrow_mut!(self.io.sockets).release(self.handle.get())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -437,57 +449,59 @@ impl<'a> TcpStream<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_lower<'b>(&'b self) -> RefMut<'b, TcpSocketLower> {
|
fn with_lower<F, R>(&self, f: F) -> R
|
||||||
RefMut::map(borrow_mut!(self.io.sockets),
|
where F: FnOnce(SocketRef<TcpSocketLower>) -> R {
|
||||||
|sockets| sockets.get_mut(self.handle).as_socket())
|
let mut sockets = borrow_mut!(self.io.sockets);
|
||||||
|
let result = f(sockets.get(self.handle));
|
||||||
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_open(&self) -> bool {
|
pub fn is_open(&self) -> bool {
|
||||||
self.as_lower().is_open()
|
self.with_lower(|s| s.is_open())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn may_send(&self) -> bool {
|
pub fn may_send(&self) -> bool {
|
||||||
self.as_lower().may_send()
|
self.with_lower(|s| s.may_send())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn may_recv(&self) -> bool {
|
pub fn may_recv(&self) -> bool {
|
||||||
self.as_lower().may_recv()
|
self.with_lower(|s| s.may_recv())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn can_send(&self) -> bool {
|
pub fn can_send(&self) -> bool {
|
||||||
self.as_lower().can_send()
|
self.with_lower(|s| s.can_send())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn can_recv(&self) -> bool {
|
pub fn can_recv(&self) -> bool {
|
||||||
self.as_lower().can_recv()
|
self.with_lower(|s| s.can_recv())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn local_endpoint(&self) -> IpEndpoint {
|
pub fn local_endpoint(&self) -> IpEndpoint {
|
||||||
self.as_lower().local_endpoint()
|
self.with_lower(|s| s.local_endpoint())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remote_endpoint(&self) -> IpEndpoint {
|
pub fn remote_endpoint(&self) -> IpEndpoint {
|
||||||
self.as_lower().remote_endpoint()
|
self.with_lower(|s| s.remote_endpoint())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn timeout(&self) -> Option<u64> {
|
pub fn timeout(&self) -> Option<u64> {
|
||||||
self.as_lower().timeout()
|
self.with_lower(|s| s.timeout())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_timeout(&self, value: Option<u64>) {
|
pub fn set_timeout(&self, value: Option<u64>) {
|
||||||
self.as_lower().set_timeout(value)
|
self.with_lower(|mut s| s.set_timeout(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn keep_alive(&self) -> Option<u64> {
|
pub fn keep_alive(&self) -> Option<u64> {
|
||||||
self.as_lower().keep_alive()
|
self.with_lower(|s| s.keep_alive())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_keep_alive(&self, value: Option<u64>) {
|
pub fn set_keep_alive(&self, value: Option<u64>) {
|
||||||
self.as_lower().set_keep_alive(value)
|
self.with_lower(|mut s| s.set_keep_alive(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn close(&self) -> Result<()> {
|
pub fn close(&self) -> Result<()> {
|
||||||
self.as_lower().close();
|
self.with_lower(|mut s| s.close());
|
||||||
until!(self, TcpSocketLower, |s| !s.is_open())?;
|
until!(self, TcpSocketLower, |s| !s.is_open())?;
|
||||||
// right now the socket may be in TIME-WAIT state. if we don't give it a chance to send
|
// right now the socket may be in TIME-WAIT state. if we don't give it a chance to send
|
||||||
// a packet, and the user code executes a loop { s.listen(); s.read(); s.close(); }
|
// a packet, and the user code executes a loop { s.listen(); s.read(); s.close(); }
|
||||||
|
@ -499,12 +513,12 @@ impl<'a> TcpStream<'a> {
|
||||||
impl<'a> Read for TcpStream<'a> {
|
impl<'a> Read for TcpStream<'a> {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
|
||||||
// Only borrow the underlying socket for the span of the next statement.
|
// Only borrow the underlying socket for the span of the next statement.
|
||||||
let result = self.as_lower().recv_slice(buf);
|
let result = self.with_lower(|mut s| s.recv_slice(buf));
|
||||||
match result {
|
match result {
|
||||||
// Slow path: we need to block until buffer is non-empty.
|
// Slow path: we need to block until buffer is non-empty.
|
||||||
Ok(0) => {
|
Ok(0) => {
|
||||||
until!(self, TcpSocketLower, |s| s.can_recv() || !s.may_recv())?;
|
until!(self, TcpSocketLower, |s| s.can_recv() || !s.may_recv())?;
|
||||||
match self.as_lower().recv_slice(buf) {
|
match self.with_lower(|mut s| s.recv_slice(buf)) {
|
||||||
Ok(length) => Ok(length),
|
Ok(length) => Ok(length),
|
||||||
Err(ErrorLower::Illegal) => Ok(0),
|
Err(ErrorLower::Illegal) => Ok(0),
|
||||||
_ => unreachable!()
|
_ => unreachable!()
|
||||||
|
@ -523,12 +537,12 @@ impl<'a> Read for TcpStream<'a> {
|
||||||
impl<'a> Write for TcpStream<'a> {
|
impl<'a> Write for TcpStream<'a> {
|
||||||
fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
||||||
// Only borrow the underlying socket for the span of the next statement.
|
// Only borrow the underlying socket for the span of the next statement.
|
||||||
let result = self.as_lower().send_slice(buf);
|
let result = self.with_lower(|mut s| s.send_slice(buf));
|
||||||
match result {
|
match result {
|
||||||
// Slow path: we need to block until buffer is non-full.
|
// Slow path: we need to block until buffer is non-full.
|
||||||
Ok(0) => {
|
Ok(0) => {
|
||||||
until!(self, TcpSocketLower, |s| s.can_send() || !s.may_send())?;
|
until!(self, TcpSocketLower, |s| s.can_send() || !s.may_send())?;
|
||||||
match self.as_lower().send_slice(buf) {
|
match self.with_lower(|mut s| s.send_slice(buf)) {
|
||||||
Ok(length) => Ok(length),
|
Ok(length) => Ok(length),
|
||||||
Err(ErrorLower::Illegal) => Ok(0),
|
Err(ErrorLower::Illegal) => Ok(0),
|
||||||
_ => unreachable!()
|
_ => unreachable!()
|
||||||
|
@ -545,7 +559,7 @@ impl<'a> Write for TcpStream<'a> {
|
||||||
|
|
||||||
fn flush(&mut self) -> Result<()> {
|
fn flush(&mut self) -> Result<()> {
|
||||||
until!(self, TcpSocketLower, |s| s.send_queue() == 0 || !s.may_send())?;
|
until!(self, TcpSocketLower, |s| s.send_queue() == 0 || !s.may_send())?;
|
||||||
if self.as_lower().send_queue() == 0 {
|
if self.with_lower(|s| s.send_queue()) == 0 {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(Error::new(ErrorKind::ConnectionAborted, "connection aborted"))
|
Err(Error::new(ErrorKind::ConnectionAborted, "connection aborted"))
|
||||||
|
@ -555,7 +569,7 @@ impl<'a> Write for TcpStream<'a> {
|
||||||
|
|
||||||
impl<'a> Drop for TcpStream<'a> {
|
impl<'a> Drop for TcpStream<'a> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.as_lower().close();
|
self.with_lower(|mut s| s.close());
|
||||||
borrow_mut!(self.io.sockets).release(self.handle)
|
borrow_mut!(self.io.sockets).release(self.handle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue