Skip to content
Permalink
Browse files

Rip out track_task to fix http_bench bug

  • Loading branch information...
ry committed Mar 14, 2019
1 parent 3551b82 commit bb999d7bb81b8fe1a7a642bb2e19f37257fcae0b
Showing with 1 addition and 61 deletions.
  1. +0 −38 src/resources.rs
  2. +1 −23 src/tokio_util.rs
@@ -175,50 +175,12 @@ impl Resource {
}
}

/// Track the current task (for TcpListener resource).
/// Throws an error if another task is already tracked.
pub fn track_task(&mut self) -> Result<(), std::io::Error> {
let mut table = RESOURCE_TABLE.lock().unwrap();
// Only track if is TcpListener.
if let Some(Repr::TcpListener(_, t)) = table.get_mut(&self.rid) {
// Currently, we only allow tracking a single accept task for a listener.
// This might be changed in the future with multiple workers.
// Caveat: TcpListener by itself also only tracks an accept task at a time.
// See https://github.com/tokio-rs/tokio/issues/846#issuecomment-454208883
if t.is_some() {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
"Another accept task is ongoing",
));
}
t.replace(futures::task::current());
}
Ok(())
}

/// Stop tracking a task (for TcpListener resource).
/// Happens when the task is done and thus no further tracking is needed.
pub fn untrack_task(&mut self) {
let mut table = RESOURCE_TABLE.lock().unwrap();
// Only untrack if is TcpListener.
if let Some(Repr::TcpListener(_, t)) = table.get_mut(&self.rid) {
// DO NOT assert is_some here.
// See reasoning in Accept::poll().
t.take();
}
}

// close(2) is done by dropping the value. Therefore we just need to remove
// the resource from the RESOURCE_TABLE.
pub fn close(&self) {
let mut table = RESOURCE_TABLE.lock().unwrap();
let r = table.remove(&self.rid);
assert!(r.is_some());
// If TcpListener, we must kill all pending accepts!
if let Repr::TcpListener(_, Some(t)) = r.unwrap() {
// Call notify on the tracked task, so that they would error out.
t.notify();
}
}

pub fn shutdown(&mut self, how: Shutdown) -> Result<(), DenoError> {
@@ -71,29 +71,7 @@ impl Future for Accept {

fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
let (stream, addr) = match self.state {
// 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).
AcceptState::Pending(ref mut r) => match r.poll_accept() {
Ok(futures::prelude::Async::Ready(t)) => {
// Notice: it is possible to be Ready on the first poll.
// When eager accept fails due to WouldBlock,
// a next poll() might still be immediately Ready.
// See https://github.com/denoland/deno/issues/1756.
r.untrack_task();
t
}
Ok(futures::prelude::Async::NotReady) => {
// Would error out if another accept task is being tracked.
r.track_task()?;
return Ok(futures::prelude::Async::NotReady);
}
Err(e) => {
r.untrack_task();
return Err(e);
}
},
AcceptState::Pending(ref mut r) => try_ready!(r.poll_accept()),
AcceptState::Empty => panic!("poll Accept after it's done"),
};

0 comments on commit bb999d7

Please sign in to comment.
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.