From 0d7e13f646cdf156a11cb406c800b3d5d6b1eb5e Mon Sep 17 00:00:00 2001 From: Mukilan Thiyagarajan Date: Mon, 13 Oct 2014 08:58:48 +0530 Subject: [PATCH] Issue #3236 - Implement timers (setTimeout/setInterval) for workers --- .../script/dom/dedicatedworkerglobalscope.rs | 7 +- .../dom/webidls/WorkerGlobalScope.webidl | 2 +- components/script/dom/window.rs | 173 ++--------------- components/script/dom/workerglobalscope.rs | 43 ++++- components/script/lib.rs | 1 + components/script/script_task.rs | 17 +- components/script/timers.rs | 178 ++++++++++++++++++ ...lhttprequest-timeout-worker-twice.html.ini | 1 + .../wpt/metadata/html/dom/interfaces.html.ini | 12 -- .../WorkerUtils/WindowTimers/001.html.ini | 6 - .../WorkerUtils/WindowTimers/003.html.ini | 6 - 11 files changed, 261 insertions(+), 185 deletions(-) create mode 100644 components/script/timers.rs delete mode 100644 tests/wpt/metadata/workers/interfaces/WorkerUtils/WindowTimers/001.html.ini delete mode 100644 tests/wpt/metadata/workers/interfaces/WorkerUtils/WindowTimers/003.html.ini diff --git a/components/script/dom/dedicatedworkerglobalscope.rs b/components/script/dom/dedicatedworkerglobalscope.rs index 22e5c4c64545..1f402b736895 100644 --- a/components/script/dom/dedicatedworkerglobalscope.rs +++ b/components/script/dom/dedicatedworkerglobalscope.rs @@ -15,10 +15,10 @@ use dom::eventtarget::WorkerGlobalScopeTypeId; use dom::messageevent::MessageEvent; use dom::worker::{Worker, TrustedWorkerAddress}; use dom::workerglobalscope::DedicatedGlobalScope; -use dom::workerglobalscope::WorkerGlobalScope; +use dom::workerglobalscope::{WorkerGlobalScope, WorkerGlobalScopeHelpers}; use dom::xmlhttprequest::XMLHttpRequest; use script_task::{ScriptTask, ScriptChan}; -use script_task::{ScriptMsg, DOMMessage, XHRProgressMsg, WorkerRelease}; +use script_task::{ScriptMsg, FromWorker, DOMMessage, FireTimerMsg, XHRProgressMsg, WorkerRelease}; use script_task::WorkerPostMessage; use script_task::StackRootTLS; @@ -142,6 +142,9 @@ impl DedicatedWorkerGlobalScope { Ok(WorkerRelease(addr)) => { Worker::handle_release(addr) }, + Ok(FireTimerMsg(FromWorker, timer_id)) => { + scope.handle_fire_timer(timer_id, js_context.ptr); + } Ok(_) => fail!("Unexpected message"), Err(_) => break, } diff --git a/components/script/dom/webidls/WorkerGlobalScope.webidl b/components/script/dom/webidls/WorkerGlobalScope.webidl index 38c9bc02d4f1..abb15523d98e 100644 --- a/components/script/dom/webidls/WorkerGlobalScope.webidl +++ b/components/script/dom/webidls/WorkerGlobalScope.webidl @@ -22,7 +22,7 @@ partial interface WorkerGlobalScope { // not obsolete void importScripts(DOMString... urls); readonly attribute WorkerNavigator navigator; }; -//WorkerGlobalScope implements WindowTimers; +WorkerGlobalScope implements WindowTimers; WorkerGlobalScope implements WindowBase64; // Proprietary diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 9a7eeef11c06..2090cd0819d3 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -20,63 +20,30 @@ use dom::performance::Performance; use dom::screen::Screen; use layout_interface::{ReflowGoal, ReflowForDisplay}; use page::Page; -use script_task::{ExitWindowMsg, FireTimerMsg, ScriptChan, TriggerLoadMsg, TriggerFragmentMsg}; +use script_task::{ExitWindowMsg, ScriptChan, TriggerLoadMsg, TriggerFragmentMsg}; +use script_task::FromWindow; use script_traits::ScriptControlChan; +use timers::{TimerId, TimerManager}; use servo_msg::compositor_msg::ScriptListener; use servo_msg::constellation_msg::LoadData; use servo_net::image_cache_task::ImageCacheTask; use servo_util::str::{DOMString,HTML_SPACE_CHARACTERS}; -use servo_util::task::{spawn_named}; -use js::jsapi::{JS_CallFunctionValue, JS_EvaluateUCScript}; +use js::jsapi::JS_EvaluateUCScript; use js::jsapi::JSContext; use js::jsapi::{JS_GC, JS_GetRuntime}; -use js::jsval::JSVal; -use js::jsval::{UndefinedValue, NullValue}; +use js::jsval::{JSVal, UndefinedValue}; use js::rust::with_compartment; use url::{Url, UrlParser}; use libc; use serialize::base64::{FromBase64, ToBase64, STANDARD}; -use std::collections::hashmap::HashMap; -use std::cell::{Cell, Ref, RefCell}; -use std::cmp; -use std::comm::{channel, Sender}; -use std::comm::Select; +use std::cell::{Ref, RefCell}; use std::default::Default; -use std::hash::{Hash, sip}; -use std::io::timer::Timer; -use std::ptr; use std::rc::Rc; -use std::time::duration::Duration; use time; -#[deriving(PartialEq, Eq)] -#[jstraceable] -pub struct TimerId(i32); - -#[jstraceable] -#[privatize] -pub struct TimerHandle { - handle: TimerId, - data: TimerData, - cancel_chan: Option>, -} - -impl Hash for TimerId { - fn hash(&self, state: &mut sip::SipState) { - let TimerId(id) = *self; - id.hash(state); - } -} - -impl TimerHandle { - fn cancel(&mut self) { - self.cancel_chan.as_ref().map(|chan| chan.send_opt(()).ok()); - } -} - #[jstraceable] #[must_root] #[privatize] @@ -88,8 +55,6 @@ pub struct Window { location: MutNullableJS, navigator: MutNullableJS, image_cache_task: ImageCacheTask, - active_timers: RefCell>, - next_timer_handle: Cell, compositor: Box, browser_context: RefCell>, page: Rc, @@ -97,6 +62,7 @@ pub struct Window { navigation_start: u64, navigation_start_precise: f64, screen: MutNullableJS, + timers: TimerManager } impl Window { @@ -142,25 +108,6 @@ impl Window { } } -#[unsafe_destructor] -impl Drop for Window { - fn drop(&mut self) { - for (_, timer_handle) in self.active_timers.borrow_mut().iter_mut() { - timer_handle.cancel(); - } - } -} - -// Holder for the various JS values associated with setTimeout -// (ie. function value to invoke and all arguments to pass -// to the function when calling it) -#[jstraceable] -#[privatize] -pub struct TimerData { - is_interval: bool, - funval: JSVal, -} - // http://www.whatwg.org/html/#atob pub fn base64_btoa(btoa: DOMString) -> Fallible { let input = btoa.as_slice(); @@ -278,21 +225,23 @@ impl<'a> WindowMethods for JSRef<'a, Window> { } fn SetTimeout(self, _cx: *mut JSContext, callback: JSVal, timeout: i32) -> i32 { - self.set_timeout_or_interval(callback, timeout, false) + self.timers.set_timeout_or_interval(callback, + timeout, + false, // is_interval + FromWindow(self.page.id.clone()), + self.script_chan.clone()) } fn ClearTimeout(self, handle: i32) { - let mut timers = self.active_timers.borrow_mut(); - let mut timer_handle = timers.pop(&TimerId(handle)); - match timer_handle { - Some(ref mut handle) => handle.cancel(), - None => { } - } - timers.remove(&TimerId(handle)); + self.timers.clear_timeout_or_interval(handle); } fn SetInterval(self, _cx: *mut JSContext, callback: JSVal, timeout: i32) -> i32 { - self.set_timeout_or_interval(callback, timeout, true) + self.timers.set_timeout_or_interval(callback, + timeout, + true, // is_interval + FromWindow(self.page.id.clone()), + self.script_chan.clone()) } fn ClearInterval(self, handle: i32) { @@ -408,9 +357,6 @@ pub trait WindowHelpers { fn evaluate_js_with_result(self, code: &str) -> JSVal; } -trait PrivateWindowHelpers { - fn set_timeout_or_interval(self, callback: JSVal, timeout: i32, is_interval: bool) -> i32; -} impl<'a> WindowHelpers for JSRef<'a, Window> { fn evaluate_js_with_result(self, code: &str) -> JSVal { @@ -471,85 +417,7 @@ impl<'a> WindowHelpers for JSRef<'a, Window> { fn handle_fire_timer(self, timer_id: TimerId, cx: *mut JSContext) { let this_value = self.reflector().get_jsobject(); - - let data = match self.active_timers.borrow().find(&timer_id) { - None => return, - Some(timer_handle) => timer_handle.data, - }; - - // TODO: Support extra arguments. This requires passing a `*JSVal` array as `argv`. - with_compartment(cx, this_value, || { - let mut rval = NullValue(); - unsafe { - JS_CallFunctionValue(cx, this_value, data.funval, - 0, ptr::null_mut(), &mut rval); - } - }); - - if !data.is_interval { - self.active_timers.borrow_mut().remove(&timer_id); - } - } -} - -impl<'a> PrivateWindowHelpers for JSRef<'a, Window> { - fn set_timeout_or_interval(self, callback: JSVal, timeout: i32, is_interval: bool) -> i32 { - let timeout = cmp::max(0, timeout) as u64; - let handle = self.next_timer_handle.get(); - self.next_timer_handle.set(handle + 1); - - // Post a delayed message to the per-window timer task; it will dispatch it - // to the relevant script handler that will deal with it. - let tm = Timer::new().unwrap(); - let (cancel_chan, cancel_port) = channel(); - let chan = self.script_chan.clone(); - let page_id = self.page.id.clone(); - let spawn_name = if is_interval { - "Window:SetInterval" - } else { - "Window:SetTimeout" - }; - spawn_named(spawn_name, proc() { - let mut tm = tm; - let duration = Duration::milliseconds(timeout as i64); - let timeout_port = if is_interval { - tm.periodic(duration) - } else { - tm.oneshot(duration) - }; - let cancel_port = cancel_port; - - let select = Select::new(); - let mut timeout_handle = select.handle(&timeout_port); - unsafe { timeout_handle.add() }; - let mut cancel_handle = select.handle(&cancel_port); - unsafe { cancel_handle.add() }; - - loop { - let id = select.wait(); - if id == timeout_handle.id() { - timeout_port.recv(); - let ScriptChan(ref chan) = chan; - chan.send(FireTimerMsg(page_id, TimerId(handle))); - if !is_interval { - break; - } - } else if id == cancel_handle.id() { - break; - } - } - }); - let timer_id = TimerId(handle); - let timer = TimerHandle { - handle: timer_id, - cancel_chan: Some(cancel_chan), - data: TimerData { - is_interval: is_interval, - funval: callback, - } - }; - self.active_timers.borrow_mut().insert(timer_id, timer); - handle + self.timers.fire_timer(timer_id, this_value, cx); } } @@ -571,13 +439,12 @@ impl Window { location: Default::default(), navigator: Default::default(), image_cache_task: image_cache_task, - active_timers: RefCell::new(HashMap::new()), - next_timer_handle: Cell::new(0), browser_context: RefCell::new(None), performance: Default::default(), navigation_start: time::get_time().sec as u64, navigation_start_precise: time::precise_time_s(), screen: Default::default(), + timers: TimerManager::new() }; WindowBinding::Wrap(cx, win) diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs index a545cf05fbee..69f2c926320c 100644 --- a/components/script/dom/workerglobalscope.rs +++ b/components/script/dom/workerglobalscope.rs @@ -12,12 +12,14 @@ use dom::eventtarget::{EventTarget, WorkerGlobalScopeTypeId}; use dom::workerlocation::WorkerLocation; use dom::workernavigator::WorkerNavigator; use dom::window::{base64_atob, base64_btoa}; -use script_task::ScriptChan; +use script_task::{ScriptChan, FromWorker}; +use timers::{TimerId, TimerManager}; use servo_net::resource_task::{ResourceTask, load_whole_resource}; use servo_util::str::DOMString; use js::jsapi::JSContext; +use js::jsval::JSVal; use js::rust::Cx; use std::default::Default; @@ -42,6 +44,7 @@ pub struct WorkerGlobalScope { location: MutNullableJS, navigator: MutNullableJS, console: MutNullableJS, + timers: TimerManager, } impl WorkerGlobalScope { @@ -59,6 +62,7 @@ impl WorkerGlobalScope { location: Default::default(), navigator: Default::default(), console: Default::default(), + timers: TimerManager::new() } } @@ -152,6 +156,43 @@ impl<'a> WorkerGlobalScopeMethods for JSRef<'a, WorkerGlobalScope> { fn Atob(self, atob: DOMString) -> Fallible { base64_atob(atob) } + + fn SetTimeout(self, _cx: *mut JSContext, handler: JSVal, timeout: i32) -> i32 { + self.timers.set_timeout_or_interval(handler, + timeout, + false, // is_interval + FromWorker, + self.script_chan.clone()) + } + + fn ClearTimeout(self, handle: i32) { + self.timers.clear_timeout_or_interval(handle); + } + + fn SetInterval(self, _cx: *mut JSContext, handler: JSVal, timeout: i32) -> i32 { + self.timers.set_timeout_or_interval(handler, + timeout, + true, // is_interval + FromWorker, + self.script_chan.clone()) + } + + fn ClearInterval(self, handle: i32) { + self.ClearTimeout(handle); + } +} + +pub trait WorkerGlobalScopeHelpers { + fn handle_fire_timer(self, timer_id: TimerId, cx: *mut JSContext); +} + +impl<'a> WorkerGlobalScopeHelpers for JSRef<'a, WorkerGlobalScope> { + + fn handle_fire_timer(self, timer_id: TimerId, cx: *mut JSContext) { + let this_value = self.reflector().get_jsobject(); + self.timers.fire_timer(timer_id, this_value, cx); + } + } impl Reflectable for WorkerGlobalScope { diff --git a/components/script/lib.rs b/components/script/lib.rs index 09bea1b73bdc..5a242cd5c8b8 100644 --- a/components/script/lib.rs +++ b/components/script/lib.rs @@ -217,3 +217,4 @@ pub mod html { pub mod layout_interface; pub mod page; pub mod script_task; +mod timers; diff --git a/components/script/script_task.rs b/components/script/script_task.rs index 4901a3e9e204..17259132eb6e 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -24,7 +24,7 @@ use dom::uievent::UIEvent; use dom::eventtarget::{EventTarget, EventTargetHelpers}; use dom::node; use dom::node::{ElementNodeTypeId, Node, NodeHelpers}; -use dom::window::{TimerId, Window, WindowHelpers}; +use dom::window::{Window, WindowHelpers}; use dom::worker::{Worker, TrustedWorkerAddress}; use dom::xmlhttprequest::{TrustedXHRAddress, XMLHttpRequest, XHRProgress}; use html::hubbub_html_parser::{InputString, InputUrl, HtmlParserResult, HtmlDiscoveredScript}; @@ -32,6 +32,7 @@ use html::hubbub_html_parser; use layout_interface::{ScriptLayoutChan, LayoutChan, ReflowForDisplay}; use layout_interface; use page::{Page, IterablePage, Frame}; +use timers::TimerId; use devtools_traits; use devtools_traits::{DevtoolsControlChan, DevtoolsControlPort, NewGlobal, NodeInfo, GetRootNode}; @@ -73,6 +74,11 @@ use std::u32; local_data_key!(pub StackRoots: *const RootCollection) +pub enum TimerSource { + FromWindow(PipelineId), + FromWorker +} + /// Messages used to control script event loops, such as ScriptTask and /// DedicatedWorkerGlobalScope. pub enum ScriptMsg { @@ -85,8 +91,10 @@ pub enum ScriptMsg { /// Instructs the script task to send a navigate message to /// the constellation (only dispatched to ScriptTask). NavigateMsg(NavigationDirection), - /// Fires a JavaScript timeout (only dispatched to ScriptTask). - FireTimerMsg(PipelineId, TimerId), + /// Fires a JavaScript timeout + /// TimerSource must be FromWindow when dispatched to ScriptTask and + /// must be FromWorker when dispatched to a DedicatedGlobalWorkerScope + FireTimerMsg(TimerSource, TimerId), /// Notifies the script that a window associated with a particular pipeline /// should be closed (only dispatched to ScriptTask). ExitWindowMsg(PipelineId), @@ -497,7 +505,8 @@ impl ScriptTask { FromScript(TriggerLoadMsg(id, load_data)) => self.trigger_load(id, load_data), FromScript(TriggerFragmentMsg(id, url)) => self.trigger_fragment(id, url), FromConstellation(SendEventMsg(id, event)) => self.handle_event(id, event), - FromScript(FireTimerMsg(id, timer_id)) => self.handle_fire_timer_msg(id, timer_id), + FromScript(FireTimerMsg(FromWindow(id), timer_id)) => self.handle_fire_timer_msg(id, timer_id), + FromScript(FireTimerMsg(FromWorker, _)) => fail!("Worker timeouts must not be sent to script task"), FromScript(NavigateMsg(direction)) => self.handle_navigate_msg(direction), FromConstellation(ReflowCompleteMsg(id, reflow_id)) => self.handle_reflow_complete_msg(id, reflow_id), FromConstellation(ResizeInactiveMsg(id, new_size)) => self.handle_resize_inactive_msg(id, new_size), diff --git a/components/script/timers.rs b/components/script/timers.rs new file mode 100644 index 000000000000..d6fe8cb206cb --- /dev/null +++ b/components/script/timers.rs @@ -0,0 +1,178 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use script_task::{FireTimerMsg, ScriptChan}; +use script_task::{TimerSource, FromWindow, FromWorker}; + +use servo_util::task::spawn_named; + +use js::jsapi::JS_CallFunctionValue; +use js::jsapi::{JSContext, JSObject}; +use js::jsval::{JSVal, NullValue}; +use js::rust::with_compartment; + +use std::cell::{Cell, RefCell}; +use std::cmp; +use std::collections::hashmap::HashMap; +use std::comm::{channel, Sender}; +use std::comm::Select; +use std::hash::{Hash, sip}; +use std::io::timer::Timer; +use std::ptr; +use std::time::duration::Duration; + +#[deriving(PartialEq, Eq)] +#[jstraceable] +pub struct TimerId(i32); + +#[jstraceable] +#[privatize] +struct TimerHandle { + handle: TimerId, + data: TimerData, + cancel_chan: Option>, +} + +impl Hash for TimerId { + fn hash(&self, state: &mut sip::SipState) { + let TimerId(id) = *self; + id.hash(state); + } +} + +impl TimerHandle { + fn cancel(&mut self) { + self.cancel_chan.as_ref().map(|chan| chan.send_opt(()).ok()); + } +} + +#[jstraceable] +#[privatize] +pub struct TimerManager { + active_timers: RefCell>, + next_timer_handle: Cell, +} + + +#[unsafe_destructor] +impl Drop for TimerManager { + fn drop(&mut self) { + for (_, timer_handle) in self.active_timers.borrow_mut().iter_mut() { + timer_handle.cancel(); + } + } +} + +// Holder for the various JS values associated with setTimeout +// (ie. function value to invoke and all arguments to pass +// to the function when calling it) +#[jstraceable] +#[privatize] +struct TimerData { + is_interval: bool, + funval: JSVal, +} + +impl TimerManager { + pub fn new() -> TimerManager { + TimerManager { + active_timers: RefCell::new(HashMap::new()), + next_timer_handle: Cell::new(0) + } + } + + pub fn set_timeout_or_interval(&self, + callback: JSVal, + timeout: i32, + is_interval: bool, + source: TimerSource, + script_chan: ScriptChan) + -> i32 { + let timeout = cmp::max(0, timeout) as u64; + let handle = self.next_timer_handle.get(); + self.next_timer_handle.set(handle + 1); + + // Spawn a new timer task; it will dispatch the FireTimerMsg + // to the relevant script handler that will deal with it. + let tm = Timer::new().unwrap(); + let (cancel_chan, cancel_port) = channel(); + let spawn_name = match source { + FromWindow(_) if is_interval => "Window:SetInterval", + FromWorker if is_interval => "Worker:SetInterval", + FromWindow(_) => "Window:SetTimeout", + FromWorker => "Worker:SetTimeout", + }; + spawn_named(spawn_name, proc() { + let mut tm = tm; + let duration = Duration::milliseconds(timeout as i64); + let timeout_port = if is_interval { + tm.periodic(duration) + } else { + tm.oneshot(duration) + }; + let cancel_port = cancel_port; + + let select = Select::new(); + let mut timeout_handle = select.handle(&timeout_port); + unsafe { timeout_handle.add() }; + let mut cancel_handle = select.handle(&cancel_port); + unsafe { cancel_handle.add() }; + + loop { + let id = select.wait(); + if id == timeout_handle.id() { + timeout_port.recv(); + let ScriptChan(ref chan) = script_chan; + chan.send(FireTimerMsg(source, TimerId(handle))); + if !is_interval { + break; + } + } else if id == cancel_handle.id() { + break; + } + } + }); + let timer_id = TimerId(handle); + let timer = TimerHandle { + handle: timer_id, + cancel_chan: Some(cancel_chan), + data: TimerData { + is_interval: is_interval, + funval: callback, + } + }; + self.active_timers.borrow_mut().insert(timer_id, timer); + handle + } + + pub fn clear_timeout_or_interval(&self, handle: i32) { + let mut timer_handle = self.active_timers.borrow_mut().pop(&TimerId(handle)); + match timer_handle { + Some(ref mut handle) => handle.cancel(), + None => { } + } + } + + pub fn fire_timer(&self, timer_id: TimerId, this: *mut JSObject, cx: *mut JSContext) { + + let data = match self.active_timers.borrow().find(&timer_id) { + None => return, + Some(timer_handle) => timer_handle.data, + }; + + // TODO: Support extra arguments. This requires passing a `*JSVal` array as `argv`. + with_compartment(cx, this, || { + let mut rval = NullValue(); + unsafe { + JS_CallFunctionValue(cx, this, data.funval, + 0, ptr::null_mut(), &mut rval); + } + }); + + if !data.is_interval { + self.active_timers.borrow_mut().remove(&timer_id); + } + } +} + diff --git a/tests/wpt/metadata/XMLHttpRequest/xmlhttprequest-timeout-worker-twice.html.ini b/tests/wpt/metadata/XMLHttpRequest/xmlhttprequest-timeout-worker-twice.html.ini index 0b136d619be7..a47308284269 100644 --- a/tests/wpt/metadata/XMLHttpRequest/xmlhttprequest-timeout-worker-twice.html.ini +++ b/tests/wpt/metadata/XMLHttpRequest/xmlhttprequest-timeout-worker-twice.html.ini @@ -1,3 +1,4 @@ [xmlhttprequest-timeout-worker-twice.html] type: testharness + disabled: xhr issue #3630 expected: TIMEOUT diff --git a/tests/wpt/metadata/html/dom/interfaces.html.ini b/tests/wpt/metadata/html/dom/interfaces.html.ini index 2b46a2166244..f07343bcef9b 100644 --- a/tests/wpt/metadata/html/dom/interfaces.html.ini +++ b/tests/wpt/metadata/html/dom/interfaces.html.ini @@ -9333,21 +9333,9 @@ [WorkerGlobalScope interface: operation createImageBitmap(ImageBitmapSource,long,long,long,long)] expected: FAIL - [WorkerGlobalScope interface: operation setTimeout(Function,long,any)] - expected: FAIL - - [WorkerGlobalScope interface: operation setTimeout(DOMString,long,any)] - expected: FAIL - [WorkerGlobalScope interface: operation clearTimeout(long)] expected: FAIL - [WorkerGlobalScope interface: operation setInterval(Function,long,any)] - expected: FAIL - - [WorkerGlobalScope interface: operation setInterval(DOMString,long,any)] - expected: FAIL - [WorkerGlobalScope interface: operation clearInterval(long)] expected: FAIL diff --git a/tests/wpt/metadata/workers/interfaces/WorkerUtils/WindowTimers/001.html.ini b/tests/wpt/metadata/workers/interfaces/WorkerUtils/WindowTimers/001.html.ini deleted file mode 100644 index 7631fc89463f..000000000000 --- a/tests/wpt/metadata/workers/interfaces/WorkerUtils/WindowTimers/001.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[001.html] - type: testharness - expected: TIMEOUT - [setTimeout] - expected: TIMEOUT - diff --git a/tests/wpt/metadata/workers/interfaces/WorkerUtils/WindowTimers/003.html.ini b/tests/wpt/metadata/workers/interfaces/WorkerUtils/WindowTimers/003.html.ini deleted file mode 100644 index 0aab6d675073..000000000000 --- a/tests/wpt/metadata/workers/interfaces/WorkerUtils/WindowTimers/003.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[003.html] - type: testharness - expected: TIMEOUT - [setInterval] - expected: TIMEOUT -