From 11569119e633ce663696e299437c657e0d085bae Mon Sep 17 00:00:00 2001 From: Surma Date: Fri, 6 Nov 2026 19:47:15 +0000 Subject: [PATCH] cred: initialize V8 inside its Tokio executor and verify concurrent limits --- host/src/cred/v8.rs | 11 +++++++---- host/tests/cred_v8.rs | 9 +++++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/host/src/cred/v8.rs b/host/src/cred/v8.rs index f437791..3b2f1ad 100644 --- a/host/src/cred/v8.rs +++ b/host/src/cred/v8.rs @@ -51,6 +51,12 @@ fn evaluate( .max_memory_bytes .unwrap_or(8 * 1024 * 1024) .clamp(256 * 1024, 32 * 1024 * 1024); + // V8 uses Tokio for internal delayed tasks, even without guest extensions. + let executor = tokio::runtime::Builder::new_current_thread() + .enable_time() + .build() + .map_err(|_| failure(ErrorKind::Engine))?; + let _entered = executor.enter(); let mut runtime = JsRuntime::new(RuntimeOptions { // Bootstrap before imposing the caller's budget: V8 cannot recover from // bootstrap OOM because the runtime cannot install its callback yet. @@ -160,10 +166,7 @@ fn evaluate( })), } }; - let result = tokio::runtime::Builder::new_current_thread() - .build() - .map_err(|_| failure(ErrorKind::Engine))? - .block_on(task); + let result = executor.block_on(task); let _ = done.send(()); let _ = watchdog.join(); if limited.load(Ordering::SeqCst) { diff --git a/host/tests/cred_v8.rs b/host/tests/cred_v8.rs index 6f7f3f5..6eba8fa 100644 --- a/host/tests/cred_v8.rs +++ b/host/tests/cred_v8.rs @@ -132,6 +132,8 @@ fn sandbox_and_isolation() { } #[test] fn independent_deadlines() { + // Exclude the process-wide platform initialization from the overlap check. + assert_eq!(run("export default ()=>true").unwrap(), "true"); let barrier = std::sync::Arc::new(std::sync::Barrier::new(2)); let other = barrier.clone(); let runaway = std::thread::spawn(move || { @@ -152,9 +154,12 @@ fn independent_deadlines() { ); }); barrier.wait(); - let start = Instant::now(); + // The quick call keeps its default 100 ms execution deadline. assert_eq!(run("export default ()=>true").unwrap(), "true"); - assert!(start.elapsed() < Duration::from_millis(500)); + assert!( + !runaway.is_finished(), + "the quick call must finish before the runaway call" + ); runaway.join().unwrap(); }