mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
net: clean shutdown of the async runtime (#38425)
The previous use of a static variable for the runtime prevented it from shutting down cleanly, because shutdown requires dropping or taking ownership of it. This PR switches the static variable to a handle only, and introduces a new trait to pass a handle to the async runtime to the constellation, where it can be shut-down along with other components and help reduce our count of still running threads after shutdown. Testing: manual testing, and covered by unit-test in net, and wpt tests. Fixes: part of - https://github.com/servo/servo/issues/30849 --------- Signed-off-by: gterzian <2792687+gterzian@users.noreply.github.com>
This commit is contained in:
parent
7ad32f944f
commit
77ff351cde
11 changed files with 132 additions and 49 deletions
|
@ -26,6 +26,7 @@ use http_body_util::combinators::BoxBody;
|
|||
use hyper::body::{Bytes, Incoming};
|
||||
use hyper::{Request as HyperRequest, Response as HyperResponse};
|
||||
use mime::{self, Mime};
|
||||
use net::async_runtime::spawn_blocking_task;
|
||||
use net::fetch::cors_cache::CorsCache;
|
||||
use net::fetch::methods::{self, FetchContext};
|
||||
use net::filemanager_thread::FileManager;
|
||||
|
@ -200,7 +201,7 @@ fn test_fetch_blob() {
|
|||
expected: bytes.to_vec(),
|
||||
};
|
||||
|
||||
crate::HANDLE.block_on(methods::fetch(request, &mut target, &context));
|
||||
spawn_blocking_task::<_, Response>(methods::fetch(request, &mut target, &context));
|
||||
|
||||
let fetch_response = receiver.recv().unwrap();
|
||||
assert!(!fetch_response.is_network_error());
|
||||
|
|
|
@ -49,7 +49,7 @@ use url::Url;
|
|||
|
||||
use crate::{
|
||||
create_embedder_proxy_and_receiver, fetch, fetch_with_context, make_body, make_server,
|
||||
new_fetch_context, receive_credential_prompt_msgs,
|
||||
new_fetch_context, receive_credential_prompt_msgs, spawn_blocking_task,
|
||||
};
|
||||
|
||||
fn mock_origin() -> ImmutableOrigin {
|
||||
|
@ -1611,7 +1611,7 @@ fn test_fetch_compressed_response_update_count() {
|
|||
sender: Some(sender),
|
||||
update_count: 0,
|
||||
};
|
||||
let response_update_count = crate::HANDLE.block_on(async move {
|
||||
let response_update_count = spawn_blocking_task::<_, Response>(async move {
|
||||
methods::fetch(
|
||||
request,
|
||||
&mut target,
|
||||
|
|
|
@ -37,6 +37,7 @@ use hyper::server::conn::http1;
|
|||
use hyper::service::service_fn;
|
||||
use hyper::{Request as HyperRequest, Response as HyperResponse};
|
||||
use hyper_util::rt::tokio::TokioIo;
|
||||
use net::async_runtime::{init_async_runtime, spawn_blocking_task, spawn_task};
|
||||
use net::connector::{create_http_client, create_tls_config};
|
||||
use net::fetch::cors_cache::CorsCache;
|
||||
use net::fetch::methods::{self, FetchContext};
|
||||
|
@ -48,25 +49,19 @@ use net::test::HttpState;
|
|||
use net_traits::filemanager_thread::FileTokenCheck;
|
||||
use net_traits::request::Request;
|
||||
use net_traits::response::Response;
|
||||
use net_traits::{FetchTaskTarget, ResourceFetchTiming, ResourceTimingType};
|
||||
use net_traits::{AsyncRuntime, FetchTaskTarget, ResourceFetchTiming, ResourceTimingType};
|
||||
use rustls_pemfile::{certs, pkcs8_private_keys};
|
||||
use rustls_pki_types::{CertificateDer, PrivateKeyDer};
|
||||
use servo_arc::Arc as ServoArc;
|
||||
use servo_url::ServoUrl;
|
||||
use tokio::net::{TcpListener, TcpStream};
|
||||
use tokio::runtime::{Builder, Runtime};
|
||||
use tokio_rustls::{self, TlsAcceptor};
|
||||
|
||||
pub static HANDLE: LazyLock<Runtime> = LazyLock::new(|| {
|
||||
Builder::new_multi_thread()
|
||||
.enable_io()
|
||||
.worker_threads(10)
|
||||
.build()
|
||||
.unwrap()
|
||||
});
|
||||
|
||||
const DEFAULT_USER_AGENT: &'static str = "Such Browser. Very Layout. Wow.";
|
||||
|
||||
static ASYNC_RUNTIME: LazyLock<Arc<Mutex<Box<dyn AsyncRuntime>>>> =
|
||||
LazyLock::new(|| Arc::new(Mutex::new(init_async_runtime())));
|
||||
|
||||
struct FetchResponseCollector {
|
||||
sender: Option<tokio::sync::oneshot::Sender<Response>>,
|
||||
}
|
||||
|
@ -168,6 +163,8 @@ fn new_fetch_context(
|
|||
fc: Option<EmbedderProxy>,
|
||||
pool_handle: Option<Weak<CoreResourceThreadPool>>,
|
||||
) -> FetchContext {
|
||||
let _ = &*ASYNC_RUNTIME;
|
||||
|
||||
let sender = fc.unwrap_or_else(|| create_embedder_proxy());
|
||||
|
||||
FetchContext {
|
||||
|
@ -208,7 +205,7 @@ fn fetch_with_context(request: Request, mut context: &mut FetchContext) -> Respo
|
|||
let mut target = FetchResponseCollector {
|
||||
sender: Some(sender),
|
||||
};
|
||||
HANDLE.block_on(async move {
|
||||
spawn_blocking_task::<_, Response>(async move {
|
||||
methods::fetch(request, &mut target, &mut context).await;
|
||||
receiver.await.unwrap()
|
||||
})
|
||||
|
@ -219,14 +216,9 @@ fn fetch_with_cors_cache(request: Request, cache: &mut CorsCache) -> Response {
|
|||
let mut target = FetchResponseCollector {
|
||||
sender: Some(sender),
|
||||
};
|
||||
HANDLE.block_on(async move {
|
||||
methods::fetch_with_cors_cache(
|
||||
request,
|
||||
cache,
|
||||
&mut target,
|
||||
&mut new_fetch_context(None, None, None),
|
||||
)
|
||||
.await;
|
||||
let mut fetch_context = new_fetch_context(None, None, None);
|
||||
spawn_blocking_task::<_, Response>(async move {
|
||||
methods::fetch_with_cors_cache(request, cache, &mut target, &mut fetch_context).await;
|
||||
receiver.await.unwrap()
|
||||
})
|
||||
}
|
||||
|
@ -249,11 +241,15 @@ where
|
|||
+ Sync
|
||||
+ 'static,
|
||||
{
|
||||
let _ = &*ASYNC_RUNTIME;
|
||||
let handler = Arc::new(handler);
|
||||
|
||||
let listener = StdTcpListener::bind("0.0.0.0:0").unwrap();
|
||||
listener.set_nonblocking(true).unwrap();
|
||||
let listener = HANDLE.block_on(async move { TcpListener::from_std(listener).unwrap() });
|
||||
let listener =
|
||||
spawn_blocking_task::<_, TcpListener>(
|
||||
async move { TcpListener::from_std(listener).unwrap() },
|
||||
);
|
||||
|
||||
let url_string = format!("http://localhost:{}", listener.local_addr().unwrap().port());
|
||||
let url = ServoUrl::parse(&url_string).unwrap();
|
||||
|
@ -290,13 +286,13 @@ where
|
|||
}),
|
||||
);
|
||||
let conn = graceful.watch(conn);
|
||||
HANDLE.spawn(async move {
|
||||
spawn_task(async move {
|
||||
let _ = conn.await;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
let _ = HANDLE.spawn(server);
|
||||
let _ = spawn_task(server);
|
||||
(
|
||||
Server {
|
||||
close_channel: tx,
|
||||
|
@ -337,10 +333,14 @@ where
|
|||
+ Sync
|
||||
+ 'static,
|
||||
{
|
||||
let _ = &*ASYNC_RUNTIME;
|
||||
let handler = Arc::new(handler);
|
||||
let listener = StdTcpListener::bind("[::0]:0").unwrap();
|
||||
listener.set_nonblocking(true).unwrap();
|
||||
let listener = HANDLE.block_on(async move { TcpListener::from_std(listener).unwrap() });
|
||||
let listener =
|
||||
spawn_blocking_task::<_, TcpListener>(
|
||||
async move { TcpListener::from_std(listener).unwrap() },
|
||||
);
|
||||
|
||||
let url_string = format!("http://localhost:{}", listener.local_addr().unwrap().port());
|
||||
let url = ServoUrl::parse(&url_string).unwrap();
|
||||
|
@ -400,7 +400,7 @@ where
|
|||
}
|
||||
};
|
||||
|
||||
HANDLE.spawn(server);
|
||||
spawn_task(server);
|
||||
|
||||
(
|
||||
Server {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue