Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make async-std compile for wasm32-unknown-unknown #225

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ matrix:
- rust: nightly-x86_64-pc-windows-msvc
os: windows

- name: wasm
rust: nightly
os: linux
before_script: |
rustup target add wasm32-unknown-unknown
script:
- cargo check --target wasm32-unknown-unknown --features unstable --all --benches --bins --examples --tests

- name: fmt
rust: nightly
os: linux
Expand Down
6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,15 @@ futures-timer = "0.4.0"
lazy_static = "1.4.0"
log = { version = "0.4.8", features = ["kv_unstable"] }
memchr = "2.2.1"
mio = "0.6.19"
mio-uds = "0.6.7"
num_cpus = "1.10.1"
pin-utils = "0.1.0-alpha.4"
slab = "0.4.2"
kv-log-macro = "1.0.4"

[target.'cfg(not(target_os = "unknown"))'.dependencies]
mio = "0.6.19"
mio-uds = "0.6.7"

[dev-dependencies]
femme = "1.2.0"
surf = "1.0.2"
Expand Down
2 changes: 2 additions & 0 deletions src/net/driver/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![cfg(not(target_os = "unknown"))]

use std::fmt;
use std::sync::{Arc, Mutex};

Expand Down
142 changes: 104 additions & 38 deletions src/net/tcp/listener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,20 @@ use std::pin::Pin;
use cfg_if::cfg_if;

use super::TcpStream;
use crate::future::{self, Future};
use crate::future::Future;
use crate::io;
use crate::net::driver::Watcher;
use crate::net::ToSocketAddrs;
use crate::stream::Stream;
use crate::task::{Context, Poll};

cfg_if! {
if #[cfg(not(target_os = "unknown"))] {
use crate::future;
use crate::net::driver::Watcher;
use super::stream::Inner as TcpStreamInner;
}
}

/// A TCP socket server, listening for connections.
///
/// After creating a `TcpListener` by [`bind`]ing it to a socket address, it listens for incoming
Expand Down Expand Up @@ -50,7 +57,19 @@ use crate::task::{Context, Poll};
/// ```
#[derive(Debug)]
pub struct TcpListener {
watcher: Watcher<mio::net::TcpListener>,
inner: Inner,
}

cfg_if! {
if #[cfg(not(target_os = "unknown"))] {
#[derive(Debug)]
struct Inner {
watcher: Watcher<mio::net::TcpListener>,
}
} else {
#[derive(Debug)]
struct Inner;
}
}

impl TcpListener {
Expand All @@ -76,25 +95,7 @@ impl TcpListener {
///
/// [`local_addr`]: #method.local_addr
pub async fn bind<A: ToSocketAddrs>(addrs: A) -> io::Result<TcpListener> {
let mut last_err = None;

for addr in addrs.to_socket_addrs().await? {
match mio::net::TcpListener::bind(&addr) {
Ok(mio_listener) => {
return Ok(TcpListener {
watcher: Watcher::new(mio_listener),
});
}
Err(err) => last_err = Some(err),
}
}

Err(last_err.unwrap_or_else(|| {
io::Error::new(
io::ErrorKind::InvalidInput,
"could not resolve to any addresses",
)
}))
bind(addrs).await
}

/// Accepts a new incoming connection to this listener.
Expand All @@ -114,15 +115,7 @@ impl TcpListener {
/// # Ok(()) }) }
/// ```
pub async fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
let (io, addr) =
future::poll_fn(|cx| self.watcher.poll_read_with(cx, |inner| inner.accept_std()))
.await?;

let mio_stream = mio::net::TcpStream::from_stream(io)?;
let stream = TcpStream {
watcher: Watcher::new(mio_stream),
};
Ok((stream, addr))
accept(self).await
}

/// Returns a stream of incoming connections.
Expand Down Expand Up @@ -173,7 +166,7 @@ impl TcpListener {
/// # Ok(()) }) }
/// ```
pub fn local_addr(&self) -> io::Result<SocketAddr> {
self.watcher.get_ref().local_addr()
local_addr(self)
}
}

Expand Down Expand Up @@ -206,10 +199,7 @@ impl<'a> Stream for Incoming<'a> {
impl From<std::net::TcpListener> for TcpListener {
/// Converts a `std::net::TcpListener` into its asynchronous equivalent.
fn from(listener: std::net::TcpListener) -> TcpListener {
let mio_listener = mio::net::TcpListener::from_std(listener).unwrap();
TcpListener {
watcher: Watcher::new(mio_listener),
}
from(listener)
}
}

Expand All @@ -229,7 +219,7 @@ cfg_if! {
if #[cfg(any(unix, feature = "docs"))] {
impl AsRawFd for TcpListener {
fn as_raw_fd(&self) -> RawFd {
self.watcher.get_ref().as_raw_fd()
self.inner.watcher.get_ref().as_raw_fd()
}
}

Expand All @@ -241,7 +231,7 @@ cfg_if! {

impl IntoRawFd for TcpListener {
fn into_raw_fd(self) -> RawFd {
self.watcher.into_inner().into_raw_fd()
self.inner.watcher.into_inner().into_raw_fd()
}
}
}
Expand Down Expand Up @@ -269,3 +259,79 @@ cfg_if! {
// }
}
}

cfg_if! {
if #[cfg(not(target_os = "unknown"))] {
async fn bind<A: ToSocketAddrs>(addrs: A) -> io::Result<TcpListener> {
let mut last_err = None;

for addr in addrs.to_socket_addrs().await? {
match mio::net::TcpListener::bind(&addr) {
Ok(mio_listener) => {
return Ok(TcpListener {
inner: Inner {
watcher: Watcher::new(mio_listener),
},
});
}
Err(err) => last_err = Some(err),
}
}

Err(last_err.unwrap_or_else(|| {
io::Error::new(
io::ErrorKind::InvalidInput,
"could not resolve to any addresses",
)
}))
}

async fn accept(listener: &TcpListener) -> io::Result<(TcpStream, SocketAddr)> {
let (io, addr) =
future::poll_fn(|cx| listener.inner.watcher.poll_read_with(cx, |inner| inner.accept_std()))
.await?;

let mio_stream = mio::net::TcpStream::from_stream(io)?;
let stream = TcpStream {
inner: TcpStreamInner {
watcher: Watcher::new(mio_stream),
},
};
Ok((stream, addr))
}

fn local_addr(listener: &TcpListener) -> io::Result<SocketAddr> {
listener.inner.watcher.get_ref().local_addr()
}

fn from(listener: std::net::TcpListener) -> TcpListener {
let mio_listener = mio::net::TcpListener::from_std(listener).unwrap();
TcpListener {
inner: Inner {
watcher: Watcher::new(mio_listener),
},
}
}

} else {
async fn bind<A: ToSocketAddrs>(_: A) -> io::Result<TcpListener> {
Err(io::Error::new(
io::ErrorKind::Other,
"TCP sockets unsupported on this platform",
))
}

async fn accept(_: &TcpListener) -> io::Result<(TcpStream, SocketAddr)> {
unreachable!()
}

fn local_addr(_: &TcpListener) -> io::Result<SocketAddr> {
unreachable!()
}

fn from(_: std::net::TcpListener) -> TcpListener {
// We can never successfully build a `std::net::TcpListener` on an unknown OS.
unreachable!()
}
}
}
Loading