summaryrefslogtreecommitdiff
path: root/ext/web/message_port.rs
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2024-04-16 19:41:03 +0100
committerGitHub <noreply@github.com>2024-04-16 18:41:03 +0000
commit760d64bc6b200ae58e8ee948903bf1e42b6799b5 (patch)
treeb92428b98e639228c847a01fcff6e2d3f036e413 /ext/web/message_port.rs
parent534dd34f8662691c1e29cc1a6b84f18d311fe0c9 (diff)
fix(ext/node): worker_threads.receiveMessageOnPort doesn't panic (#23406)
Follow up to https://github.com/denoland/deno/pull/23386. Instead of using async `recv()` method, it was replaced with a poll based function that doesn't hold onto RefCell borrow across await point. Fixes https://github.com/denoland/deno/issues/23362
Diffstat (limited to 'ext/web/message_port.rs')
-rw-r--r--ext/web/message_port.rs16
1 files changed, 10 insertions, 6 deletions
diff --git a/ext/web/message_port.rs b/ext/web/message_port.rs
index ac33145b1..c069037f8 100644
--- a/ext/web/message_port.rs
+++ b/ext/web/message_port.rs
@@ -15,6 +15,7 @@ use deno_core::OpState;
use deno_core::RcRef;
use deno_core::Resource;
use deno_core::ResourceId;
+use futures::future::poll_fn;
use serde::Deserialize;
use serde::Serialize;
use tokio::sync::mpsc::error::TryRecvError;
@@ -52,16 +53,19 @@ impl MessagePort {
Ok(())
}
- #[allow(clippy::await_holding_refcell_ref)] // TODO(ry) remove!
pub async fn recv(
&self,
state: Rc<RefCell<OpState>>,
) -> Result<Option<JsMessageData>, AnyError> {
- let mut rx = self
- .rx
- .try_borrow_mut()
- .map_err(|_| type_error("Port receiver is already borrowed"))?;
- if let Some((data, transferables)) = rx.recv().await {
+ let rx = &self.rx;
+
+ let maybe_data = poll_fn(|cx| {
+ let mut rx = rx.borrow_mut();
+ rx.poll_recv(cx)
+ })
+ .await;
+
+ if let Some((data, transferables)) = maybe_data {
let js_transferables =
serialize_transferables(&mut state.borrow_mut(), transferables);
return Ok(Some(JsMessageData {