summaryrefslogtreecommitdiff
path: root/runtime/ops/http.rs
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2021-06-14 14:52:49 +0200
committerGitHub <noreply@github.com>2021-06-14 14:52:49 +0200
commit1e1959f6fac6dd0e499532772c8143285cdd81de (patch)
treea321b9351d1d860b4e6026896cc45966cae96c8d /runtime/ops/http.rs
parent5814315b708d154ebb2c29810c16e5af7e726741 (diff)
fix: hang in Deno.serveHttp() (#10923)
Waiting on next request in Deno.serveHttp() API hanged when responses were using ReadableStream. This was caused by op_http_request_next op that was never woken after response was fully written. This commit adds waker field to DenoService which is called after response is finished.
Diffstat (limited to 'runtime/ops/http.rs')
-rw-r--r--runtime/ops/http.rs20
1 files changed, 13 insertions, 7 deletions
diff --git a/runtime/ops/http.rs b/runtime/ops/http.rs
index fedcb404f..11e83f6c7 100644
--- a/runtime/ops/http.rs
+++ b/runtime/ops/http.rs
@@ -66,6 +66,7 @@ struct ServiceInner {
#[derive(Clone, Default)]
struct Service {
inner: Rc<RefCell<Option<ServiceInner>>>,
+ waker: Rc<deno_core::futures::task::AtomicWaker>,
}
impl HyperService<Request<Body>> for Service {
@@ -160,15 +161,16 @@ async fn op_http_request_next(
let cancel = RcRef::map(conn_resource.clone(), |r| &r.cancel);
poll_fn(|cx| {
+ conn_resource.deno_service.waker.register(cx.waker());
let connection_closed = match conn_resource.poll(cx) {
Poll::Pending => false,
Poll::Ready(Ok(())) => {
- // close ConnResource
- state
+ // try to close ConnResource, but don't unwrap as it might
+ // already be closed
+ let _ = state
.borrow_mut()
.resource_table
- .take::<ConnResource>(conn_rid)
- .unwrap();
+ .take::<ConnResource>(conn_rid);
true
}
Poll::Ready(Err(e)) => {
@@ -188,7 +190,6 @@ async fn op_http_request_next(
}
}
};
-
if let Some(request_resource) =
conn_resource.deno_service.inner.borrow_mut().take()
{
@@ -409,6 +410,9 @@ async fn op_http_response(
})
.await?;
+ if maybe_response_body_rid.is_none() {
+ conn_resource.deno_service.waker.wake();
+ }
Ok(maybe_response_body_rid)
}
@@ -430,11 +434,13 @@ async fn op_http_response_close(
.ok_or_else(bad_resource_id)?;
drop(resource);
- poll_fn(|cx| match conn_resource.poll(cx) {
+ let r = poll_fn(|cx| match conn_resource.poll(cx) {
Poll::Ready(x) => Poll::Ready(x),
Poll::Pending => Poll::Ready(Ok(())),
})
- .await
+ .await;
+ conn_resource.deno_service.waker.wake();
+ r
}
async fn op_http_request_read(