1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-23 07:44:48 -05:00

Optimization: eager accept

This commit is contained in:
Ryan Dahl 2018-10-19 18:38:27 -04:00
parent aac9e204b7
commit 92b0a94c23
2 changed files with 54 additions and 2 deletions

View file

@ -10,7 +10,6 @@ use isolate::Op;
use msg;
use resources;
use resources::Resource;
use tokio_util;
use version;
use flatbuffers::FlatBufferBuilder;
@ -1185,7 +1184,7 @@ fn op_accept(
match resources::lookup(server_rid) {
None => odd_future(errors::bad_resource()),
Some(server_resource) => {
let op = tokio_util::accept(server_resource)
let op = resources::eager_accept(server_resource)
.map_err(|err| DenoError::from(err))
.and_then(move |(tcp_stream, _socket_addr)| {
new_conn(cmd_id, tcp_stream)

View file

@ -9,6 +9,7 @@
// handlers) look up resources by their integer id here.
use errors::DenoError;
use tokio_util;
use tokio_write;
use futures;
@ -291,3 +292,55 @@ where
},
}
}
type EagerAccept = Either<
tokio_util::Accept,
FutureResult<(TcpStream, SocketAddr), std::io::Error>,
>;
#[cfg(windows)]
pub fn eager_accept(resource: Resource) -> EagerAccept {
Either::A(tokio_util::accept(resource)).into()
}
// This is an optimization that Tokio should do.
// Attempt to call write() on the main thread.
#[cfg(not(windows))]
pub fn eager_accept(resource: Resource) -> EagerAccept {
let mut table = RESOURCE_TABLE.lock().unwrap();
let maybe_repr = table.get_mut(&resource.rid);
match maybe_repr {
None => panic!("bad rid"),
Some(repr) => match repr {
Repr::TcpListener(ref mut listener) => {
// Unforunately we can't just call write() on tokio::net::TcpStream
use std::os::unix::io::AsRawFd;
use std::os::unix::io::FromRawFd;
use std::os::unix::io::IntoRawFd;
let mut std_listener =
unsafe { std::net::TcpListener::from_raw_fd(listener.as_raw_fd()) };
let result = std_listener.accept();
// std_listener will close when it gets dropped. Thus...
let _ = std_listener.into_raw_fd();
match result {
Ok((std_stream, addr)) => {
let result = tokio::net::TcpStream::from_std(
std_stream,
&tokio::reactor::Handle::default(),
);
let tokio_stream = result.unwrap();
Either::B(futures::future::ok((tokio_stream, addr)))
}
Err(err) => {
if err.kind() == std::io::ErrorKind::WouldBlock {
Either::A(tokio_util::accept(resource))
} else {
Either::B(futures::future::err(err))
}
}
}
}
_ => Either::A(tokio_util::accept(resource)),
},
}
}