Bug 757133: Implement a WorkerDebuggerManager; r=khuey

This commit is contained in:
Eddy Bruël 2014-10-27 18:00:05 +01:00
parent 26bbf370e9
commit b739736c39
16 changed files with 733 additions and 15 deletions

View File

@ -235,6 +235,7 @@
#ifdef MOZ_WEBSPEECH
@BINPATH@/components/dom_webspeechrecognition.xpt
#endif
@BINPATH@/components/dom_workers.xpt
@BINPATH@/components/dom_xbl.xpt
@BINPATH@/components/dom_xpath.xpt
@BINPATH@/components/dom_xul.xpt

View File

@ -0,0 +1,236 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* 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/. */
#include "WorkerDebuggerManager.h"
#include "nsISimpleEnumerator.h"
#include "WorkerPrivate.h"
USING_WORKERS_NAMESPACE
class RegisterDebuggerRunnable MOZ_FINAL : public nsRunnable
{
nsRefPtr<WorkerDebuggerManager> mManager;
nsRefPtr<WorkerDebugger> mDebugger;
bool mHasListeners;
public:
RegisterDebuggerRunnable(WorkerDebuggerManager* aManager,
WorkerDebugger* aDebugger,
bool aHasListeners)
: mManager(aManager), mDebugger(aDebugger), mHasListeners(aHasListeners)
{ }
NS_DECL_THREADSAFE_ISUPPORTS
private:
~RegisterDebuggerRunnable()
{ }
NS_IMETHOD
Run() MOZ_OVERRIDE
{
mManager->RegisterDebuggerOnMainThread(mDebugger, mHasListeners);
return NS_OK;
}
};
NS_IMPL_ISUPPORTS(RegisterDebuggerRunnable, nsIRunnable);
BEGIN_WORKERS_NAMESPACE
class WorkerDebuggerEnumerator MOZ_FINAL : public nsISimpleEnumerator
{
nsTArray<nsCOMPtr<nsISupports>> mDebuggers;
uint32_t mIndex;
public:
WorkerDebuggerEnumerator(const nsTArray<WorkerDebugger*>& aDebuggers)
: mIndex(0)
{
mDebuggers.AppendElements(aDebuggers);
}
NS_DECL_ISUPPORTS
NS_DECL_NSISIMPLEENUMERATOR
private:
~WorkerDebuggerEnumerator() {}
};
NS_IMPL_ISUPPORTS(WorkerDebuggerEnumerator, nsISimpleEnumerator);
NS_IMETHODIMP
WorkerDebuggerEnumerator::HasMoreElements(bool* aResult)
{
*aResult = mIndex < mDebuggers.Length();
return NS_OK;
};
NS_IMETHODIMP
WorkerDebuggerEnumerator::GetNext(nsISupports** aResult)
{
if (mIndex == mDebuggers.Length()) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsISupports> element = mDebuggers.ElementAt(mIndex++);
element.forget(aResult);
return NS_OK;
};
WorkerDebuggerManager::WorkerDebuggerManager()
: mMutex("WorkerDebuggerManager::mMutex")
{
AssertIsOnMainThread();
}
WorkerDebuggerManager::~WorkerDebuggerManager()
{
AssertIsOnMainThread();
}
NS_IMPL_ISUPPORTS(WorkerDebuggerManager, nsIWorkerDebuggerManager);
NS_IMETHODIMP
WorkerDebuggerManager::GetWorkerDebuggerEnumerator(
nsISimpleEnumerator** aResult)
{
AssertIsOnMainThread();
MutexAutoLock lock(mMutex);
nsRefPtr<WorkerDebuggerEnumerator> enumerator =
new WorkerDebuggerEnumerator(mDebuggers);
enumerator.forget(aResult);
return NS_OK;
}
NS_IMETHODIMP
WorkerDebuggerManager::AddListener(nsIWorkerDebuggerManagerListener* aListener)
{
AssertIsOnMainThread();
MutexAutoLock lock(mMutex);
if (mListeners.Contains(aListener)) {
return NS_ERROR_INVALID_ARG;
}
mListeners.AppendElement(aListener);
return NS_OK;
}
NS_IMETHODIMP
WorkerDebuggerManager::RemoveListener(
nsIWorkerDebuggerManagerListener* aListener)
{
AssertIsOnMainThread();
MutexAutoLock lock(mMutex);
if (!mListeners.Contains(aListener)) {
return NS_OK;
}
mListeners.RemoveElement(aListener);
return NS_OK;
}
void
WorkerDebuggerManager::RegisterDebugger(WorkerDebugger* aDebugger)
{
// May be called on any thread!
bool hasListeners = false;
{
MutexAutoLock lock(mMutex);
hasListeners = !mListeners.IsEmpty();
}
if (NS_IsMainThread()) {
RegisterDebuggerOnMainThread(aDebugger, hasListeners);
} else {
nsCOMPtr<nsIRunnable> runnable =
new RegisterDebuggerRunnable(this, aDebugger, hasListeners);
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
NS_DispatchToMainThread(runnable, NS_DISPATCH_NORMAL)));
if (hasListeners) {
aDebugger->WaitIsEnabled(true);
}
}
}
void
WorkerDebuggerManager::UnregisterDebugger(WorkerDebugger* aDebugger)
{
// May be called on any thread!
if (NS_IsMainThread()) {
UnregisterDebuggerOnMainThread(aDebugger);
} else {
nsCOMPtr<nsIRunnable> runnable =
NS_NewRunnableMethodWithArg<nsRefPtr<WorkerDebugger>>(this,
&WorkerDebuggerManager::UnregisterDebuggerOnMainThread, aDebugger);
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
NS_DispatchToMainThread(runnable, NS_DISPATCH_NORMAL)));
aDebugger->WaitIsEnabled(false);
}
}
void
WorkerDebuggerManager::RegisterDebuggerOnMainThread(WorkerDebugger* aDebugger,
bool aHasListeners)
{
AssertIsOnMainThread();
MOZ_ASSERT(!mDebuggers.Contains(aDebugger));
mDebuggers.AppendElement(aDebugger);
nsTArray<nsCOMPtr<nsIWorkerDebuggerManagerListener>> listeners;
{
MutexAutoLock lock(mMutex);
listeners.AppendElements(mListeners);
}
if (aHasListeners) {
for (size_t index = 0; index < listeners.Length(); ++index) {
listeners[index]->OnRegister(aDebugger);
}
}
aDebugger->Enable();
}
void
WorkerDebuggerManager::UnregisterDebuggerOnMainThread(WorkerDebugger* aDebugger)
{
AssertIsOnMainThread();
MOZ_ASSERT(mDebuggers.Contains(aDebugger));
mDebuggers.RemoveElement(aDebugger);
nsTArray<nsCOMPtr<nsIWorkerDebuggerManagerListener>> listeners;
{
MutexAutoLock lock(mMutex);
listeners.AppendElements(mListeners);
}
for (size_t index = 0; index < listeners.Length(); ++index) {
listeners[index]->OnUnregister(aDebugger);
}
aDebugger->Disable();
}
END_WORKERS_NAMESPACE

View File

@ -0,0 +1,95 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* 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/. */
#ifndef mozilla_dom_workers_workerdebuggermanager_h
#define mozilla_dom_workers_workerdebuggermanager_h
#include "Workers.h"
#include "nsIWorkerDebuggerManager.h"
#include "nsServiceManagerUtils.h"
#include "nsTArray.h"
#define WORKERDEBUGGERMANAGER_CID \
{ 0x62ec8731, 0x55ad, 0x4246, \
{ 0xb2, 0xea, 0xf2, 0x6c, 0x1f, 0xe1, 0x9d, 0x2d } }
#define WORKERDEBUGGERMANAGER_CONTRACTID \
"@mozilla.org/dom/workers/workerdebuggermanager;1"
class RegisterDebuggerRunnable;
BEGIN_WORKERS_NAMESPACE
class WorkerDebugger;
class WorkerDebuggerManager MOZ_FINAL : public nsIWorkerDebuggerManager
{
friend class ::RegisterDebuggerRunnable;
mozilla::Mutex mMutex;
// Protected by mMutex.
nsTArray<nsCOMPtr<nsIWorkerDebuggerManagerListener>> mListeners;
// Only touched on the main thread.
nsTArray<WorkerDebugger*> mDebuggers;
public:
static WorkerDebuggerManager*
GetOrCreateService()
{
nsCOMPtr<nsIWorkerDebuggerManager> wdm =
do_GetService(WORKERDEBUGGERMANAGER_CONTRACTID);
return static_cast<WorkerDebuggerManager*>(wdm.get());
}
WorkerDebuggerManager();
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIWORKERDEBUGGERMANAGER
void RegisterDebugger(WorkerDebugger* aDebugger);
void UnregisterDebugger(WorkerDebugger* aDebugger);
private:
virtual ~WorkerDebuggerManager();
void RegisterDebuggerOnMainThread(WorkerDebugger* aDebugger,
bool aHasListeners);
void UnregisterDebuggerOnMainThread(WorkerDebugger* aDebugger);
};
inline nsresult
RegisterWorkerDebugger(WorkerDebugger* aDebugger)
{
nsRefPtr<WorkerDebuggerManager> manager =
WorkerDebuggerManager::GetOrCreateService();
if (!manager) {
return NS_ERROR_FAILURE;
}
manager->RegisterDebugger(aDebugger);
return NS_OK;
}
inline nsresult
UnregisterWorkerDebugger(WorkerDebugger* aDebugger)
{
nsRefPtr<WorkerDebuggerManager> manager =
WorkerDebuggerManager::GetOrCreateService();
if (!manager) {
return NS_ERROR_FAILURE;
}
manager->UnregisterDebugger(aDebugger);
return NS_OK;
}
END_WORKERS_NAMESPACE
#endif // mozilla_dom_workers_workerdebuggermanager_h

View File

@ -27,6 +27,7 @@
#include "nsITimer.h"
#include "nsIURI.h"
#include "nsIURL.h"
#include "nsIWorkerDebugger.h"
#include "nsIXPConnect.h"
#include <algorithm>
@ -80,6 +81,7 @@
#include "ScriptLoader.h"
#include "ServiceWorkerManager.h"
#include "SharedWorker.h"
#include "WorkerDebuggerManager.h"
#include "WorkerFeature.h"
#include "WorkerRunnable.h"
#include "WorkerScope.h"
@ -656,6 +658,8 @@ private:
RuntimeService* runtime = RuntimeService::GetService();
NS_ASSERTION(runtime, "This should never be null!");
mFinishedWorker->DisableDebugger();
runtime->UnregisterWorker(aCx, mFinishedWorker);
mFinishedWorker->ClearSelfRef();
@ -690,6 +694,8 @@ private:
AutoSafeJSContext cx;
JSAutoRequest ar(cx);
mFinishedWorker->DisableDebugger();
runtime->UnregisterWorker(cx, mFinishedWorker);
nsTArray<nsCOMPtr<nsISupports> > doomed;
@ -2142,6 +2148,42 @@ WorkerPrivateParent<Derived>::DispatchPrivate(WorkerRunnable* aRunnable,
return NS_OK;
}
template <class Derived>
void
WorkerPrivateParent<Derived>::EnableDebugger()
{
AssertIsOnParentThread();
WorkerPrivate* self = ParentAsWorkerPrivate();
MOZ_ASSERT(!self->mDebugger);
self->mDebugger = new WorkerDebugger(self);
if (NS_FAILED(RegisterWorkerDebugger(self->mDebugger))) {
NS_WARNING("Failed to register worker debugger!");
self->mDebugger = nullptr;
}
}
template <class Derived>
void
WorkerPrivateParent<Derived>::DisableDebugger()
{
AssertIsOnParentThread();
WorkerPrivate* self = ParentAsWorkerPrivate();
if (!self->mDebugger) {
return;
}
if (NS_FAILED(UnregisterWorkerDebugger(self->mDebugger))) {
NS_WARNING("Failed to unregister worker debugger!");
}
self->mDebugger = nullptr;
}
template <class Derived>
nsresult
WorkerPrivateParent<Derived>::DispatchControlRunnable(
@ -3448,6 +3490,94 @@ WorkerPrivateParent<Derived>::AssertInnerWindowIsCorrect() const
}
#endif
WorkerDebugger::WorkerDebugger(WorkerPrivate* aWorkerPrivate)
: mMutex("WorkerDebugger::mMutex"),
mCondVar(mMutex, "WorkerDebugger::mCondVar"),
mWorkerPrivate(aWorkerPrivate),
mIsEnabled(false)
{
mWorkerPrivate->AssertIsOnParentThread();
}
WorkerDebugger::~WorkerDebugger()
{
MOZ_ASSERT(!mWorkerPrivate);
}
NS_IMPL_ISUPPORTS(WorkerDebugger, nsIWorkerDebugger)
NS_IMETHODIMP
WorkerDebugger::GetIsClosed(bool* aResult)
{
AssertIsOnMainThread();
MutexAutoLock lock(mMutex);
*aResult = !mWorkerPrivate;
return NS_OK;
}
NS_IMETHODIMP
WorkerDebugger::GetUrl(nsAString& aResult)
{
AssertIsOnMainThread();
MutexAutoLock lock(mMutex);
if (!mWorkerPrivate) {
return NS_ERROR_UNEXPECTED;
}
aResult = mWorkerPrivate->ScriptURL();
return NS_OK;
}
void
WorkerDebugger::WaitIsEnabled(bool aIsEnabled)
{
MutexAutoLock lock(mMutex);
while (mIsEnabled != aIsEnabled) {
mCondVar.Wait();
}
}
void
WorkerDebugger::NotifyIsEnabled(bool aIsEnabled)
{
mMutex.AssertCurrentThreadOwns();
MOZ_ASSERT(mIsEnabled != aIsEnabled);
mIsEnabled = aIsEnabled;
mCondVar.Notify();
}
void
WorkerDebugger::Enable()
{
AssertIsOnMainThread();
MutexAutoLock lock(mMutex);
MOZ_ASSERT(mWorkerPrivate);
NotifyIsEnabled(true);
}
void
WorkerDebugger::Disable()
{
AssertIsOnMainThread();
MutexAutoLock lock(mMutex);
MOZ_ASSERT(mWorkerPrivate);
mWorkerPrivate = nullptr;
NotifyIsEnabled(false);
}
WorkerPrivate::WorkerPrivate(JSContext* aCx,
WorkerPrivate* aParent,
const nsAString& aScriptURL,
@ -3621,6 +3751,8 @@ WorkerPrivate::Constructor(JSContext* aCx,
return nullptr;
}
worker->EnableDebugger();
nsRefPtr<CompileScriptRunnable> compiler = new CompileScriptRunnable(worker);
if (!compiler->Dispatch(aCx)) {
aRv.Throw(NS_ERROR_UNEXPECTED);

View File

@ -9,6 +9,7 @@
#include "Workers.h"
#include "nsIContentSecurityPolicy.h"
#include "nsIWorkerDebugger.h"
#include "nsPIDOMWindow.h"
#include "mozilla/CondVar.h"
@ -61,6 +62,7 @@ class WorkerControlRunnable;
class WorkerGlobalScope;
class WorkerPrivate;
class WorkerRunnable;
class WorkerDebugger;
enum WorkerType
{
@ -294,6 +296,12 @@ public:
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(WorkerPrivateParent,
DOMEventTargetHelper)
void
EnableDebugger();
void
DisableDebugger();
void
ClearSelfRef()
{
@ -721,6 +729,34 @@ public:
#endif
};
class WorkerDebugger : public nsIWorkerDebugger {
mozilla::Mutex mMutex;
mozilla::CondVar mCondVar;
// Protected by mMutex
WorkerPrivate* mWorkerPrivate;
bool mIsEnabled;
public:
WorkerDebugger(WorkerPrivate* aWorkerPrivate);
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIWORKERDEBUGGER
void AssertIsOnParentThread();
void WaitIsEnabled(bool aIsEnabled);
void Enable();
void Disable();
private:
virtual ~WorkerDebugger();
void NotifyIsEnabled(bool aIsEnabled);
};
class WorkerPrivate : public WorkerPrivateParent<WorkerPrivate>
{
friend class WorkerPrivateParent<WorkerPrivate>;
@ -739,6 +775,8 @@ class WorkerPrivate : public WorkerPrivateParent<WorkerPrivate>
NoTimer
};
nsRefPtr<WorkerDebugger> mDebugger;
Queue<WorkerControlRunnable*, 4> mControlQueue;
// Touched on multiple threads, protected with mMutex.

View File

@ -16,6 +16,7 @@ EXPORTS.mozilla.dom += [
EXPORTS.mozilla.dom.workers += [
'ServiceWorkerManager.h',
'WorkerDebuggerManager.h',
'Workers.h',
]
@ -36,6 +37,13 @@ EXPORTS.mozilla.dom.workers.bindings += [
'XMLHttpRequestUpload.h',
]
XPIDL_MODULE = 'dom_workers'
XPIDL_SOURCES += [
'nsIWorkerDebugger.idl',
'nsIWorkerDebuggerManager.idl',
]
UNIFIED_SOURCES += [
'ChromeWorkerScope.cpp',
'DataStore.cpp',
@ -56,6 +64,7 @@ UNIFIED_SOURCES += [
'ServiceWorkerRegistration.cpp',
'SharedWorker.cpp',
'URL.cpp',
'WorkerDebuggerManager.cpp',
'WorkerPrivate.cpp',
'WorkerRunnable.cpp',
'WorkerScope.cpp',

View File

@ -0,0 +1,9 @@
#include "nsISupports.idl"
[scriptable, builtinclass, uuid(0833b363-bffe-4cdb-ad50-1c4563e0C8ff)]
interface nsIWorkerDebugger : nsISupports
{
readonly attribute bool isClosed;
readonly attribute DOMString url;
};

View File

@ -0,0 +1,22 @@
#include "nsISupports.idl"
interface nsISimpleEnumerator;
interface nsIWorkerDebugger;
[scriptable, uuid(d2aa74ee-6b98-4d5d-8173-4e23422daf1e)]
interface nsIWorkerDebuggerManagerListener : nsISupports
{
void onRegister(in nsIWorkerDebugger debugger);
void onUnregister(in nsIWorkerDebugger debugger);
};
[scriptable, builtinclass, uuid(056d7918-dc86-452a-b4e6-86da3405f015)]
interface nsIWorkerDebuggerManager : nsISupports
{
nsISimpleEnumerator getWorkerDebuggerEnumerator();
void addListener(in nsIWorkerDebuggerManagerListener listener);
void removeListener(in nsIWorkerDebuggerManagerListener listener);
};

View File

@ -0,0 +1,3 @@
"use strict";
onmessage = function () {};

View File

@ -0,0 +1,3 @@
"use strict";
var worker = new Worker("WorkerDebuggerManager_childWorker.js");

View File

@ -1,11 +1,15 @@
[DEFAULT]
support-files =
WorkerDebuggerManager_childWorker.js
WorkerDebuggerManager_parentWorker.js
WorkerTest.jsm
WorkerTest_subworker.js
WorkerTest_worker.js
chromeWorker_subworker.js
chromeWorker_worker.js
dom_worker_helper.js
file_url.jsm
file_worker.js
fileBlobSubWorker_worker.js
fileBlob_worker.js
filePosting_worker.js
@ -20,6 +24,7 @@ support-files =
file_url.jsm
bug1062920_worker.js
[test_WorkerDebuggerManager.xul]
[test_bug883784.jsm]
[test_bug883784.xul]
[test_chromeWorker.xul]

View File

@ -3,6 +3,16 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/AddonManager.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
const wdm = Cc["@mozilla.org/dom/workers/workerdebuggermanager;1"].
getService(Ci.nsIWorkerDebuggerManager);
var gRemainingTests = 0;
function waitForWorkerFinish() {
@ -19,3 +29,74 @@ function finish() {
}
}
function assertThrows(fun, message) {
let throws = false;
try {
fun();
} catch (e) {
throws = true;
}
ok(throws, message);
}
function* generateDebuggers() {
let e = wdm.getWorkerDebuggerEnumerator();
while (e.hasMoreElements()) {
let dbg = e.getNext().QueryInterface(Ci.nsIWorkerDebugger);
yield dbg;
}
}
function findDebugger(predicate) {
for (let dbg of generateDebuggers()) {
if (predicate(dbg)) {
return dbg;
}
}
return null;
}
function waitForRegister(predicate = () => true) {
return new Promise(function (resolve) {
wdm.addListener({
onRegister: function (dbg) {
if (!predicate(dbg)) {
return;
}
wdm.removeListener(this);
resolve(dbg);
}
});
});
}
function waitForUnregister(predicate = () => true) {
return new Promise(function (resolve) {
wdm.addListener({
onUnregister: function (dbg) {
if (!predicate(dbg)) {
return;
}
wdm.removeListener(this);
resolve(dbg);
}
});
});
}
function waitForMultiple(promises) {
return new Promise(function (resolve) {
let results = [];
for (let i = 0; i < promises.length; ++i) {
let promise = promises[i];
let index = i;
promise.then(function (result) {
is(results.length, index, "events should occur in the specified order");
results.push(result);
if (results.length === promises.length) {
resolve(results);
}
});
}
});
};

View File

@ -0,0 +1,92 @@
<?xml version="1.0"?>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<window title="Test for WorkerDebuggerManager"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="test();">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
<script type="application/javascript" src="dom_worker_helper.js"/>
<script type="application/javascript">
<![CDATA[
const PARENT_WORKER_URL = "WorkerDebuggerManager_parentWorker.js";
const CHILD_WORKER_URL = "WorkerDebuggerManager_childWorker.js";
function test() {
Task.spawn(function* () {
SimpleTest.waitForExplicitFinish();
ok(!findDebugger((dbg) => dbg.url === PARENT_WORKER_URL),
"debugger for parent worker should not be enumerated before it is " +
"registered");
ok(!findDebugger((dbg) => dbg.url === CHILD_WORKER_URL),
"debugger for child worker should not be enumerated before it is " +
"registered");
let promise = waitForMultiple([
waitForRegister((dbg) => dbg.url === PARENT_WORKER_URL),
waitForRegister((dbg) => dbg.url === CHILD_WORKER_URL),
]);
let worker = new Worker(PARENT_WORKER_URL);
let dbgs = yield promise;
is(dbgs[0].isClosed, false,
"debugger for parent worker should not be closed after it is " +
"registered");
is(dbgs[1].isClosed, false,
"debugger for child worker should not be closed after it is " +
"registered");
ok(findDebugger((dbg) => dbg.url === PARENT_WORKER_URL),
"debugger for parent worker should be enumerated after it is " +
"registered");
ok(findDebugger((dbg) => dbg.url === CHILD_WORKER_URL),
"debugger for child worker should be enumerated after it is " +
"registered");
promise = waitForMultiple([
waitForUnregister((dbg) => dbg.url === CHILD_WORKER_URL),
waitForUnregister((dbg) => dbg.url === PARENT_WORKER_URL),
]);
worker.terminate();
dbgs = yield promise;
is(dbgs[0].isClosed, true,
"debugger for parent worker should be closed after it is " +
"unregistered");
is(dbgs[1].isClosed, true,
"debugger for child worker should be closed after it is " +
"unregistered");
assertThrows(() => dbgs[0].url,
"accessing debugger for parent worker should throw " +
"after it is closed");
assertThrows(() => dbgs[0].url,
"accessing debugger for child worker should throw after " +
"it is closed");
ok(!findDebugger((dbg) => dbg.url === PARENT_WORKER_URL),
"debugger for parent worker should not be enumerated after it is " +
"unregistered");
ok(!findDebugger((dbg) => dbg.url === CHILD_WORKER_URL),
"debugger for child worker should not be enumerated after it is " +
"unregistered");
SimpleTest.finish();
});
}
]]>
</script>
<body xmlns="http://www.w3.org/1999/xhtml">
<p id="display"></p>
<div id="content" style="display:none;"></div>
<pre id="test"></pre>
</body>
<label id="test-result"/>
</window>

View File

@ -16,13 +16,6 @@
<script type="application/javascript">
<![CDATA[
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
function test() {
const message = "woohoo";

View File

@ -16,14 +16,6 @@
<script type="application/javascript">
<![CDATA[
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/AddonManager.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
function test() {
const message = "woohoo";

View File

@ -90,6 +90,7 @@
#include "mozilla/dom/network/UDPSocketChild.h"
#include "mozilla/dom/quota/QuotaManager.h"
#include "mozilla/dom/workers/ServiceWorkerManager.h"
#include "mozilla/dom/workers/WorkerDebuggerManager.h"
#include "mozilla/OSFileConstants.h"
#include "mozilla/Services.h"
@ -248,6 +249,7 @@ using mozilla::dom::alarm::AlarmHalService;
using mozilla::dom::power::PowerManagerService;
using mozilla::dom::quota::QuotaManager;
using mozilla::dom::workers::ServiceWorkerManager;
using mozilla::dom::workers::WorkerDebuggerManager;
using mozilla::dom::TCPSocketChild;
using mozilla::dom::TCPSocketParent;
using mozilla::dom::TCPServerSocketChild;
@ -287,6 +289,8 @@ NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(QuotaManager,
QuotaManager::FactoryCreate)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(ServiceWorkerManager,
ServiceWorkerManager::FactoryCreate)
NS_GENERIC_FACTORY_CONSTRUCTOR(WorkerDebuggerManager)
#ifdef MOZ_WIDGET_GONK
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(SystemWorkerManager,
SystemWorkerManager::FactoryCreate)
@ -715,6 +719,7 @@ NS_DEFINE_NAMED_CID(NS_TEXTEDITOR_CID);
NS_DEFINE_NAMED_CID(DOMREQUEST_SERVICE_CID);
NS_DEFINE_NAMED_CID(QUOTA_MANAGER_CID);
NS_DEFINE_NAMED_CID(SERVICEWORKERMANAGER_CID);
NS_DEFINE_NAMED_CID(WORKERDEBUGGERMANAGER_CID);
#ifdef MOZ_WIDGET_GONK
NS_DEFINE_NAMED_CID(SYSTEMWORKERMANAGER_CID);
#endif
@ -1005,6 +1010,7 @@ static const mozilla::Module::CIDEntry kLayoutCIDs[] = {
{ &kDOMREQUEST_SERVICE_CID, false, nullptr, DOMRequestServiceConstructor },
{ &kQUOTA_MANAGER_CID, false, nullptr, QuotaManagerConstructor },
{ &kSERVICEWORKERMANAGER_CID, false, nullptr, ServiceWorkerManagerConstructor },
{ &kWORKERDEBUGGERMANAGER_CID, true, nullptr, WorkerDebuggerManagerConstructor },
#ifdef MOZ_WIDGET_GONK
{ &kSYSTEMWORKERMANAGER_CID, true, nullptr, SystemWorkerManagerConstructor },
#endif
@ -1162,6 +1168,7 @@ static const mozilla::Module::ContractIDEntry kLayoutContracts[] = {
{ DOMREQUEST_SERVICE_CONTRACTID, &kDOMREQUEST_SERVICE_CID },
{ QUOTA_MANAGER_CONTRACTID, &kQUOTA_MANAGER_CID },
{ SERVICEWORKERMANAGER_CONTRACTID, &kSERVICEWORKERMANAGER_CID },
{ WORKERDEBUGGERMANAGER_CONTRACTID, &kWORKERDEBUGGERMANAGER_CID },
#ifdef MOZ_WIDGET_GONK
{ SYSTEMWORKERMANAGER_CONTRACTID, &kSYSTEMWORKERMANAGER_CID },
#endif