mirror of
https://github.com/denoland/deno.git
synced 2024-12-26 00:59:24 -05:00
disable eager polling for ops (#3434)
This commit is contained in:
parent
2ed3592def
commit
136b5e3da2
3 changed files with 2 additions and 76 deletions
|
@ -33,7 +33,6 @@ pub fn init(i: &mut Isolate, s: &ThreadSafeState) {
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
enum AcceptState {
|
enum AcceptState {
|
||||||
Eager,
|
|
||||||
Pending,
|
Pending,
|
||||||
Done,
|
Done,
|
||||||
}
|
}
|
||||||
|
@ -41,7 +40,7 @@ enum AcceptState {
|
||||||
/// Simply accepts a connection.
|
/// Simply accepts a connection.
|
||||||
pub fn accept(state: &ThreadSafeState, rid: ResourceId) -> Accept {
|
pub fn accept(state: &ThreadSafeState, rid: ResourceId) -> Accept {
|
||||||
Accept {
|
Accept {
|
||||||
accept_state: AcceptState::Eager,
|
accept_state: AcceptState::Pending,
|
||||||
rid,
|
rid,
|
||||||
state: state.clone(),
|
state: state.clone(),
|
||||||
}
|
}
|
||||||
|
@ -78,29 +77,6 @@ impl Future for Accept {
|
||||||
futures::compat::Compat01As03::new(&mut listener_resource.listener)
|
futures::compat::Compat01As03::new(&mut listener_resource.listener)
|
||||||
.map_err(ErrBox::from);
|
.map_err(ErrBox::from);
|
||||||
|
|
||||||
if inner.accept_state == AcceptState::Eager {
|
|
||||||
// Similar to try_ready!, but also track/untrack accept task
|
|
||||||
// in TcpListener resource.
|
|
||||||
// In this way, when the listener is closed, the task can be
|
|
||||||
// notified to error out (instead of stuck forever).
|
|
||||||
match listener.poll_next_unpin(cx) {
|
|
||||||
Poll::Ready(Some(Ok(stream))) => {
|
|
||||||
inner.accept_state = AcceptState::Done;
|
|
||||||
let addr = stream.peer_addr().unwrap();
|
|
||||||
return Poll::Ready(Ok((stream, addr)));
|
|
||||||
}
|
|
||||||
Poll::Pending => {
|
|
||||||
inner.accept_state = AcceptState::Pending;
|
|
||||||
return Poll::Pending;
|
|
||||||
}
|
|
||||||
Poll::Ready(Some(Err(e))) => {
|
|
||||||
inner.accept_state = AcceptState::Done;
|
|
||||||
return Poll::Ready(Err(e));
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match listener.poll_next_unpin(cx) {
|
match listener.poll_next_unpin(cx) {
|
||||||
Poll::Ready(Some(Ok(stream))) => {
|
Poll::Ready(Some(Ok(stream))) => {
|
||||||
listener_resource.untrack_task();
|
listener_resource.untrack_task();
|
||||||
|
|
|
@ -303,7 +303,6 @@ fn op_listen_tls(
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
enum AcceptTlsState {
|
enum AcceptTlsState {
|
||||||
Eager,
|
|
||||||
Pending,
|
Pending,
|
||||||
Done,
|
Done,
|
||||||
}
|
}
|
||||||
|
@ -311,7 +310,7 @@ enum AcceptTlsState {
|
||||||
/// Simply accepts a TLS connection.
|
/// Simply accepts a TLS connection.
|
||||||
pub fn accept_tls(state: &ThreadSafeState, rid: ResourceId) -> AcceptTls {
|
pub fn accept_tls(state: &ThreadSafeState, rid: ResourceId) -> AcceptTls {
|
||||||
AcceptTls {
|
AcceptTls {
|
||||||
accept_state: AcceptTlsState::Eager,
|
accept_state: AcceptTlsState::Pending,
|
||||||
rid,
|
rid,
|
||||||
state: state.clone(),
|
state: state.clone(),
|
||||||
}
|
}
|
||||||
|
@ -348,29 +347,6 @@ impl Future for AcceptTls {
|
||||||
futures::compat::Compat01As03::new(&mut listener_resource.listener)
|
futures::compat::Compat01As03::new(&mut listener_resource.listener)
|
||||||
.map_err(ErrBox::from);
|
.map_err(ErrBox::from);
|
||||||
|
|
||||||
if inner.accept_state == AcceptTlsState::Eager {
|
|
||||||
// Similar to try_ready!, but also track/untrack accept task
|
|
||||||
// in TcpListener resource.
|
|
||||||
// In this way, when the listener is closed, the task can be
|
|
||||||
// notified to error out (instead of stuck forever).
|
|
||||||
match listener.poll_next_unpin(cx) {
|
|
||||||
Poll::Ready(Some(Ok(stream))) => {
|
|
||||||
inner.accept_state = AcceptTlsState::Done;
|
|
||||||
let addr = stream.peer_addr().unwrap();
|
|
||||||
return Poll::Ready(Ok((stream, addr)));
|
|
||||||
}
|
|
||||||
Poll::Pending => {
|
|
||||||
inner.accept_state = AcceptTlsState::Pending;
|
|
||||||
return Poll::Pending;
|
|
||||||
}
|
|
||||||
Poll::Ready(Some(Err(e))) => {
|
|
||||||
inner.accept_state = AcceptTlsState::Done;
|
|
||||||
return Poll::Ready(Err(e));
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match listener.poll_next_unpin(cx) {
|
match listener.poll_next_unpin(cx) {
|
||||||
Poll::Ready(Some(Ok(stream))) => {
|
Poll::Ready(Some(Ok(stream))) => {
|
||||||
listener_resource.untrack_task();
|
listener_resource.untrack_task();
|
||||||
|
|
|
@ -179,7 +179,6 @@ pub struct Isolate {
|
||||||
have_unpolled_ops: bool,
|
have_unpolled_ops: bool,
|
||||||
startup_script: Option<OwnedScript>,
|
startup_script: Option<OwnedScript>,
|
||||||
pub op_registry: Arc<OpRegistry>,
|
pub op_registry: Arc<OpRegistry>,
|
||||||
eager_poll_count: u32,
|
|
||||||
waker: AtomicWaker,
|
waker: AtomicWaker,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +245,6 @@ impl Isolate {
|
||||||
pending_dyn_imports: FuturesUnordered::new(),
|
pending_dyn_imports: FuturesUnordered::new(),
|
||||||
startup_script,
|
startup_script,
|
||||||
op_registry: Arc::new(OpRegistry::new()),
|
op_registry: Arc::new(OpRegistry::new()),
|
||||||
eager_poll_count: 0,
|
|
||||||
waker: AtomicWaker::new(),
|
waker: AtomicWaker::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -349,29 +347,6 @@ impl Isolate {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// To avoid latency problems we eagerly poll 50 futures and then
|
|
||||||
// allow to poll ops from `pending_ops`
|
|
||||||
let op = if isolate.eager_poll_count != 50 {
|
|
||||||
isolate.eager_poll_count += 1;
|
|
||||||
match op {
|
|
||||||
Op::Async(mut fut) => {
|
|
||||||
// Tries to eagerly poll async ops once. Often they are immediately ready, in
|
|
||||||
// which case they can be turned into a sync op before we return to V8. This
|
|
||||||
// can save a boundary crossing.
|
|
||||||
#[allow(clippy::match_wild_err_arm)]
|
|
||||||
let mut cx = Context::from_waker(futures::task::noop_waker_ref());
|
|
||||||
match fut.poll_unpin(&mut cx) {
|
|
||||||
Poll::Ready(Err(_)) => panic!("unexpected op error"),
|
|
||||||
Poll::Ready(Ok(buf)) => Op::Sync(buf),
|
|
||||||
Poll::Pending => Op::Async(fut),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Op::Sync(buf) => Op::Sync(buf),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
op
|
|
||||||
};
|
|
||||||
|
|
||||||
debug_assert_eq!(isolate.shared.size(), 0);
|
debug_assert_eq!(isolate.shared.size(), 0);
|
||||||
match op {
|
match op {
|
||||||
Op::Sync(buf) => {
|
Op::Sync(buf) => {
|
||||||
|
@ -703,7 +678,6 @@ impl Future for Isolate {
|
||||||
|
|
||||||
// Now handle actual ops.
|
// Now handle actual ops.
|
||||||
inner.have_unpolled_ops = false;
|
inner.have_unpolled_ops = false;
|
||||||
inner.eager_poll_count = 0;
|
|
||||||
#[allow(clippy::match_wild_err_arm)]
|
#[allow(clippy::match_wild_err_arm)]
|
||||||
match inner.pending_ops.poll_next_unpin(cx) {
|
match inner.pending_ops.poll_next_unpin(cx) {
|
||||||
Poll::Ready(Some(Err(_))) => panic!("unexpected op error"),
|
Poll::Ready(Some(Err(_))) => panic!("unexpected op error"),
|
||||||
|
|
Loading…
Reference in a new issue