frontend-utils: Don't use tokio tasks inside ruffle's executor

This commit is contained in:
Nathan Adams 2024-04-17 22:15:22 +02:00
parent 899fe54477
commit 5bffc33be8
2 changed files with 27 additions and 15 deletions

View File

@ -5,6 +5,7 @@ use async_channel::{unbounded, Receiver, Sender};
use ruffle_core::backend::navigator::OwnedFuture;
use ruffle_core::loader::Error;
use slotmap::{new_key_type, SlotMap};
use std::future::Future;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard, Weak};
use std::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};
@ -273,3 +274,16 @@ impl<R: PollRequester> FutureSpawner for AsyncFutureSpawner<R> {
self.poll_requester.request_poll()
}
}
/// Spawns a new asynchronous task in a tokio runtime, without the current executor needing to belong to tokio
pub async fn spawn_tokio<F>(future: F) -> F::Output
where
F: Future + Send + 'static,
F::Output: Send + 'static,
{
let (sender, receiver) = tokio::sync::oneshot::channel();
tokio::spawn(async move { sender.send(future.await) });
tokio::task::unconstrained(receiver)
.await
.expect("Oneshot should succeed")
}

View File

@ -1,6 +1,6 @@
mod fetch;
use crate::backends::executor::FutureSpawner;
use crate::backends::executor::{spawn_tokio, FutureSpawner};
use crate::backends::navigator::fetch::{Response, ResponseBody};
use crate::content::PlayingContent;
use async_channel::{Receiver, Sender, TryRecvError};
@ -25,7 +25,6 @@ use std::path::Path;
use std::rc::Rc;
use std::sync::{Arc, Mutex};
use std::time::Duration;
use tokio::task;
use tracing::warn;
use url::{ParseError, Url};
@ -238,19 +237,17 @@ impl<F: FutureSpawner, I: NavigatorInterface> NavigatorBackend for ExternalNavig
request_builder = request_builder.body(body_data);
let response = task::unconstrained(request_builder.send())
.await
.map_err(|e| {
let inner = if e.is_connect() {
Error::InvalidDomain(processed_url.to_string())
} else {
Error::FetchError(e.to_string())
};
ErrorResponse {
url: processed_url.to_string(),
error: inner,
}
})?;
let response = spawn_tokio(request_builder.send()).await.map_err(|e| {
let inner = if e.is_connect() {
Error::InvalidDomain(processed_url.to_string())
} else {
Error::FetchError(e.to_string())
};
ErrorResponse {
url: processed_url.to_string(),
error: inner,
}
})?;
let url = response.url().to_string();
@ -467,6 +464,7 @@ mod tests {
use ruffle_core::socket::SocketAction::{Close, Connect, Data};
use std::net::SocketAddr;
use std::str::FromStr;
use tokio::task;
use super::*;