зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 7 changesets (bug 1450644, bug 1454633) for for failing browser_storage_permission.js on a CLOSED TREE
Backed out changeset f4989e0da221 (bug 1454633) Backed out changeset 08239799d43e (bug 1450644) Backed out changeset cbe3ad4833b6 (bug 1450644) Backed out changeset 0d2088370d0c (bug 1450644) Backed out changeset 246fb3ee14cd (bug 1450644) Backed out changeset 629e499c0f75 (bug 1450644) Backed out changeset ed93e3547096 (bug 1450644)
This commit is contained in:
Родитель
69c328a7f6
Коммит
78bac61f63
|
@ -23,13 +23,11 @@ DOMPrefs::Initialize()
|
|||
|
||||
#define DOM_PREF(name, pref) DOMPrefs::name();
|
||||
#define DOM_WEBIDL_PREF(name)
|
||||
#define DOM_UINT32_PREF(name, pref, defaultValue) DOMPrefs::name();
|
||||
|
||||
#include "DOMPrefsInternal.h"
|
||||
|
||||
#undef DOM_PREF
|
||||
#undef DOM_WEBIDL_PREF
|
||||
#undef DOM_UINT32_PREF
|
||||
}
|
||||
|
||||
#define DOM_PREF(name, pref) \
|
||||
|
@ -52,19 +50,6 @@ DOMPrefs::Initialize()
|
|||
return DOMPrefs::name(); \
|
||||
}
|
||||
|
||||
#define DOM_UINT32_PREF(name, pref, defaultValue) \
|
||||
/* static */ uint32_t \
|
||||
DOMPrefs::name() \
|
||||
{ \
|
||||
static bool initialized = false; \
|
||||
static Atomic<uint32_t> cachedValue; \
|
||||
if (!initialized) { \
|
||||
initialized = true; \
|
||||
Preferences::AddAtomicUintVarCache(&cachedValue, pref, defaultValue); \
|
||||
} \
|
||||
return cachedValue; \
|
||||
}
|
||||
|
||||
#if !(defined(DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
|
||||
DOM_PREF(DumpEnabled, "browser.dom.window.dump.enabled")
|
||||
#else
|
||||
|
@ -79,7 +64,6 @@ DOMPrefs::DumpEnabled()
|
|||
|
||||
#undef DOM_PREF
|
||||
#undef DOM_WEBIDL_PREF
|
||||
#undef DOM_UINT32_PREF
|
||||
|
||||
} // dom namespace
|
||||
} // mozilla namespace
|
||||
|
|
|
@ -21,13 +21,11 @@ public:
|
|||
|
||||
#define DOM_PREF(name, pref) static bool name();
|
||||
#define DOM_WEBIDL_PREF(name) static bool name(JSContext* aCx, JSObject* aObj);
|
||||
#define DOM_UINT32_PREF(name, pref, defaultValue) static uint32_t name();
|
||||
|
||||
#include "DOMPrefsInternal.h"
|
||||
|
||||
#undef DOM_PREF
|
||||
#undef DOM_WEBIDL_PREF
|
||||
#undef DOM_UINT32_PREF
|
||||
};
|
||||
|
||||
} // dom namespace
|
||||
|
|
|
@ -56,7 +56,3 @@ DOM_WEBIDL_PREF(WebkitBlinkDirectoryPickerEnabled)
|
|||
DOM_WEBIDL_PREF(NetworkInformationEnabled)
|
||||
DOM_WEBIDL_PREF(FetchObserverEnabled)
|
||||
DOM_WEBIDL_PREF(PerformanceObserverEnabled)
|
||||
|
||||
DOM_UINT32_PREF(WorkerCancelingTimeoutMillis,
|
||||
"dom.worker.canceling.timeoutMilliseconds",
|
||||
30000 /* 30 seconds */)
|
||||
|
|
|
@ -311,15 +311,15 @@ BroadcastChannel::Constructor(const GlobalObject& aGlobal,
|
|||
// We are already shutting down the worker. Let's return a non-active
|
||||
// object.
|
||||
if (NS_WARN_IF(!workerRef)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
bc->mState = StateClosed;
|
||||
return bc.forget();
|
||||
}
|
||||
|
||||
RefPtr<ThreadSafeWorkerRef> tsr = new ThreadSafeWorkerRef(workerRef);
|
||||
|
||||
RefPtr<InitializeRunnable> runnable =
|
||||
new InitializeRunnable(tsr, origin, principalInfo, aRv);
|
||||
runnable->Dispatch(Canceling, aRv);
|
||||
runnable->Dispatch(Closing, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -68,6 +68,11 @@ private:
|
|||
|
||||
~BroadcastChannel();
|
||||
|
||||
void PostMessageData(BroadcastChannelMessage* aData);
|
||||
|
||||
void PostMessageInternal(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void RemoveDocFromBFCache();
|
||||
|
||||
void DisconnectFromOwner() override;
|
||||
|
|
|
@ -176,7 +176,7 @@ Client::Focus(ErrorResult& aRv)
|
|||
// and also avoid invoking callbacks if the worker starts shutting
|
||||
// down.
|
||||
RefPtr<WorkerHolderToken> token =
|
||||
WorkerHolderToken::Create(GetCurrentThreadWorkerPrivate(), Terminating);
|
||||
WorkerHolderToken::Create(GetCurrentThreadWorkerPrivate(), Closing);
|
||||
|
||||
EnsureHandle();
|
||||
RefPtr<ClientStatePromise> innerPromise = mHandle->Focus();
|
||||
|
|
|
@ -27,7 +27,7 @@ StartClientManagerOp(Func aFunc, const Arg& aArg, nsISerialEventTarget* aTarget,
|
|||
RefPtr<WorkerHolderToken> token;
|
||||
if (!NS_IsMainThread()) {
|
||||
token = WorkerHolderToken::Create(GetCurrentThreadWorkerPrivate(),
|
||||
WorkerStatus::Terminating);
|
||||
WorkerStatus::Closing);
|
||||
}
|
||||
|
||||
RefPtr<ClientOpPromise> promise = aFunc(aArg, aTarget);
|
||||
|
|
|
@ -46,7 +46,7 @@ ClientManager::ClientManager()
|
|||
MOZ_DIAGNOSTIC_ASSERT(workerPrivate);
|
||||
|
||||
workerHolderToken =
|
||||
WorkerHolderToken::Create(workerPrivate, Terminating,
|
||||
WorkerHolderToken::Create(workerPrivate, Closing,
|
||||
WorkerHolderToken::AllowIdleShutdownStart);
|
||||
if (NS_WARN_IF(!workerHolderToken)) {
|
||||
Shutdown();
|
||||
|
|
|
@ -297,8 +297,8 @@ MessagePort::Initialize(const nsID& aUUID,
|
|||
StrongWorkerRef::Create(workerPrivate, "MessagePort",
|
||||
[self]() { self->CloseForced(); });
|
||||
if (NS_WARN_IF(!strongWorkerRef)) {
|
||||
// The worker is shutting down.
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
// The worker is shutting down. Let's return an already closed port.
|
||||
mState = eStateDisentangledForClose;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -572,7 +572,7 @@ class DisconnectInternalRunnable final : public WorkerMainThreadRunnable
|
|||
{
|
||||
public:
|
||||
explicit DisconnectInternalRunnable(WebSocketImpl* aImpl)
|
||||
: WorkerMainThreadRunnable(GetCurrentThreadWorkerPrivate(),
|
||||
: WorkerMainThreadRunnable(aImpl->mWorkerRef->Private(),
|
||||
NS_LITERAL_CSTRING("WebSocket :: disconnect"))
|
||||
, mImpl(aImpl)
|
||||
{ }
|
||||
|
@ -620,7 +620,7 @@ WebSocketImpl::Disconnect()
|
|||
if (mWebSocket->GetOwner()) {
|
||||
mWebSocket->GetOwner()->UpdateWebSocketCount(-1);
|
||||
}
|
||||
} else {
|
||||
} else if (mWorkerRef) {
|
||||
RefPtr<DisconnectInternalRunnable> runnable =
|
||||
new DisconnectInternalRunnable(this);
|
||||
ErrorResult rv;
|
||||
|
@ -1403,14 +1403,18 @@ WebSocket::ConstructorCommon(const GlobalObject& aGlobal,
|
|||
}
|
||||
|
||||
if (NS_WARN_IF(!webSocketImpl->RegisterWorkerRef(workerPrivate))) {
|
||||
// The worker is shutting down.
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
// The worker is shutting down. We cannot proceed but we return a
|
||||
// 'connecting' object.
|
||||
webSocketImpl->mWorkerShuttingDown = true;
|
||||
webSocketImpl->Disconnect();
|
||||
return webSocket.forget();
|
||||
}
|
||||
|
||||
RefPtr<ConnectRunnable> connectRunnable =
|
||||
new ConnectRunnable(workerPrivate, webSocketImpl);
|
||||
connectRunnable->Dispatch(Canceling, aRv);
|
||||
// We can use Closing because we have a WorkerRef and that is enough to be
|
||||
// sure that the worker is up and running.
|
||||
connectRunnable->Dispatch(Closing, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
#include "js/MemoryMetrics.h"
|
||||
#include "MessageEventRunnable.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
#include "mozilla/dom/ClientManager.h"
|
||||
#include "mozilla/dom/ClientSource.h"
|
||||
#include "mozilla/dom/ClientState.h"
|
||||
|
@ -977,93 +976,6 @@ public:
|
|||
virtual bool Notify(WorkerStatus aStatus) override { return true; }
|
||||
};
|
||||
|
||||
// A runnable to cancel the worker from the parent thread when self.close() is
|
||||
// called. This runnable is executed on the parent process in order to cancel
|
||||
// the current runnable. It uses a normal WorkerRunnable in order to be sure
|
||||
// that all the pending WorkerRunnables are executed before this.
|
||||
class CancelingOnParentRunnable final : public WorkerRunnable
|
||||
{
|
||||
public:
|
||||
explicit CancelingOnParentRunnable(WorkerPrivate* aWorkerPrivate)
|
||||
: WorkerRunnable(aWorkerPrivate, ParentThreadUnchangedBusyCount)
|
||||
{}
|
||||
|
||||
bool
|
||||
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
|
||||
{
|
||||
aWorkerPrivate->Cancel();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// A runnable to cancel the worker from the parent process.
|
||||
class CancelingWithTimeoutOnParentRunnable final : public WorkerControlRunnable
|
||||
{
|
||||
public:
|
||||
explicit CancelingWithTimeoutOnParentRunnable(WorkerPrivate* aWorkerPrivate)
|
||||
: WorkerControlRunnable(aWorkerPrivate, ParentThreadUnchangedBusyCount)
|
||||
{}
|
||||
|
||||
bool
|
||||
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
|
||||
{
|
||||
aWorkerPrivate->AssertIsOnParentThread();
|
||||
aWorkerPrivate->StartCancelingTimer();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CancelingTimerCallback final : public nsITimerCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
explicit CancelingTimerCallback(WorkerPrivate* aWorkerPrivate)
|
||||
: mWorkerPrivate(aWorkerPrivate)
|
||||
{}
|
||||
|
||||
NS_IMETHOD
|
||||
Notify(nsITimer* aTimer) override
|
||||
{
|
||||
mWorkerPrivate->AssertIsOnParentThread();
|
||||
mWorkerPrivate->Cancel();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
~CancelingTimerCallback() = default;
|
||||
|
||||
// Raw pointer here is OK because the timer is canceled during the shutdown
|
||||
// steps.
|
||||
WorkerPrivate* mWorkerPrivate;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(CancelingTimerCallback, nsITimerCallback)
|
||||
|
||||
// This runnable starts the canceling of a worker after a self.close().
|
||||
class CancelingRunnable final : public Runnable
|
||||
{
|
||||
public:
|
||||
CancelingRunnable()
|
||||
: Runnable("CancelingRunnable")
|
||||
{}
|
||||
|
||||
NS_IMETHOD
|
||||
Run() override
|
||||
{
|
||||
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
||||
MOZ_ASSERT(workerPrivate);
|
||||
workerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
// Now we can cancel the this worker from the parent process.
|
||||
RefPtr<CancelingOnParentRunnable> r =
|
||||
new CancelingOnParentRunnable(workerPrivate);
|
||||
r->Dispatch();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
class WorkerPrivate::EventTarget final : public nsISerialEventTarget
|
||||
|
@ -1825,12 +1737,6 @@ WorkerPrivate::NotifyPrivate(WorkerStatus aStatus)
|
|||
// Anything queued will be discarded.
|
||||
mQueuedRunnables.Clear();
|
||||
|
||||
// No Canceling timeout is needed.
|
||||
if (mCancelingTimer) {
|
||||
mCancelingTimer->Cancel();
|
||||
mCancelingTimer = nullptr;
|
||||
}
|
||||
|
||||
RefPtr<NotifyRunnable> runnable = new NotifyRunnable(this, aStatus);
|
||||
return runnable->Dispatch();
|
||||
}
|
||||
|
@ -3703,13 +3609,6 @@ WorkerPrivate::InterruptCallback(JSContext* aCx)
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
WorkerPrivate::CloseInternal()
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
NotifyInternal(Closing);
|
||||
}
|
||||
|
||||
bool
|
||||
WorkerPrivate::IsOnCurrentThread()
|
||||
{
|
||||
|
@ -4579,24 +4478,8 @@ WorkerPrivate::NotifyInternal(WorkerStatus aStatus)
|
|||
return true;
|
||||
}
|
||||
|
||||
// Don't abort the script now, but we dispatch a runnable to do it when the
|
||||
// current JS frame is executed.
|
||||
// Don't abort the script.
|
||||
if (aStatus == Closing) {
|
||||
if (mSyncLoopStack.IsEmpty()) {
|
||||
// Here we use a normal runnable to know when the current JS chunk of code
|
||||
// is finished. We cannot use a WorkerRunnable because they are not
|
||||
// accepted any more by the worker, and we do not want to use a
|
||||
// WorkerControlRunnable because they are immediately executed.
|
||||
RefPtr<CancelingRunnable> r = new CancelingRunnable();
|
||||
mThread->nsThread::Dispatch(r.forget(), NS_DISPATCH_NORMAL);
|
||||
|
||||
// At the same time, we want to be sure that we interrupt infinite loops.
|
||||
// The following runnable starts a timer that cancel the worker, from the
|
||||
// parent thread, after CANCELING_TIMEOUT millseconds.
|
||||
RefPtr<CancelingWithTimeoutOnParentRunnable> rr =
|
||||
new CancelingWithTimeoutOnParentRunnable(this);
|
||||
rr->Dispatch();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -4963,48 +4846,6 @@ WorkerPrivate::RescheduleTimeoutTimer(JSContext* aCx)
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
WorkerPrivate::StartCancelingTimer()
|
||||
{
|
||||
AssertIsOnParentThread();
|
||||
|
||||
auto errorCleanup = MakeScopeExit([&] {
|
||||
mCancelingTimer = nullptr;
|
||||
});
|
||||
|
||||
MOZ_ASSERT(!mCancelingTimer);
|
||||
|
||||
if (WorkerPrivate* parent = GetParent()) {
|
||||
mCancelingTimer = NS_NewTimer(parent->ControlEventTarget());
|
||||
} else {
|
||||
mCancelingTimer = NS_NewTimer();
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!mCancelingTimer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This is not needed if we are already in an advanced shutdown state.
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
if (ParentStatus() >= Terminating) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t cancelingTimeoutMillis = DOMPrefs::WorkerCancelingTimeoutMillis();
|
||||
|
||||
RefPtr<CancelingTimerCallback> callback = new CancelingTimerCallback(this);
|
||||
nsresult rv = mCancelingTimer->InitWithCallback(callback,
|
||||
cancelingTimeoutMillis,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
errorCleanup.release();
|
||||
}
|
||||
|
||||
void
|
||||
WorkerPrivate::UpdateContextOptionsInternal(
|
||||
JSContext* aCx,
|
||||
|
|
|
@ -263,8 +263,12 @@ public:
|
|||
bool
|
||||
IsOnCurrentThread();
|
||||
|
||||
void
|
||||
CloseInternal();
|
||||
bool
|
||||
CloseInternal()
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
return NotifyInternal(Closing);
|
||||
}
|
||||
|
||||
bool
|
||||
FreezeInternal();
|
||||
|
@ -1209,9 +1213,6 @@ public:
|
|||
PrincipalIsValid() const;
|
||||
#endif
|
||||
|
||||
void
|
||||
StartCancelingTimer();
|
||||
|
||||
private:
|
||||
WorkerPrivate(WorkerPrivate* aParent,
|
||||
const nsAString& aScriptURL, bool aIsChromeWorker,
|
||||
|
@ -1424,8 +1425,6 @@ private:
|
|||
nsCOMPtr<nsITimer> mTimer;
|
||||
nsCOMPtr<nsITimerCallback> mTimerRunnable;
|
||||
|
||||
nsCOMPtr<nsITimer> mCancelingTimer;
|
||||
|
||||
nsCOMPtr<nsITimer> mGCTimer;
|
||||
|
||||
RefPtr<MemoryReporter> mMemoryReporter;
|
||||
|
|
|
@ -70,10 +70,6 @@ public:
|
|||
{
|
||||
MOZ_ASSERT(mWorkerRef);
|
||||
|
||||
if (aStatus < Canceling) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Let's keep this object alive for the whole Notify() execution.
|
||||
RefPtr<WorkerRef> workerRef;
|
||||
workerRef = mWorkerRef;
|
||||
|
@ -132,7 +128,7 @@ WeakWorkerRef::Create(WorkerPrivate* aWorkerPrivate,
|
|||
// This holder doesn't keep the worker alive.
|
||||
UniquePtr<Holder> holder(new Holder("WeakWorkerRef::Holder", ref,
|
||||
WorkerHolder::AllowIdleShutdownStart));
|
||||
if (NS_WARN_IF(!holder->HoldWorker(aWorkerPrivate, Canceling))) {
|
||||
if (NS_WARN_IF(!holder->HoldWorker(aWorkerPrivate, Closing))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -186,7 +182,7 @@ StrongWorkerRef::Create(WorkerPrivate* aWorkerPrivate,
|
|||
// The worker is kept alive by this holder.
|
||||
UniquePtr<Holder> holder(new Holder(aName, ref,
|
||||
WorkerHolder::PreventIdleShutdownStart));
|
||||
if (NS_WARN_IF(!holder->HoldWorker(aWorkerPrivate, Canceling))) {
|
||||
if (NS_WARN_IF(!holder->HoldWorker(aWorkerPrivate, Closing))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,12 +6,6 @@ self.onconnect = function (event) {
|
|||
case "close":
|
||||
close();
|
||||
break;
|
||||
|
||||
case "close_loop":
|
||||
close();
|
||||
// Let's loop forever.
|
||||
while(1) {}
|
||||
break;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
function test() {
|
||||
(async function() {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.requestLongerTimeout(5);
|
||||
|
||||
info("Create a top-level chrome worker that creates a non-top-level " +
|
||||
"content worker and wait for their debuggers to be registered.");
|
||||
|
@ -57,7 +56,7 @@
|
|||
"Non-top-level worker debugger should not have window.");
|
||||
|
||||
info("Terminate the top-level chrome worker and the non-top-level " +
|
||||
"content worker, and wait for their debuggers to be " +
|
||||
"content worker, and wait for their debuggers to be " +
|
||||
"unregistered and closed.");
|
||||
promise = waitForMultiple([
|
||||
waitForUnregister(CHILD_WORKER_URL),
|
||||
|
@ -68,7 +67,7 @@
|
|||
worker.terminate();
|
||||
await promise;
|
||||
|
||||
info("Create a shared worker and wait for its debugger to be " +
|
||||
info("Create a shared worker and wait for its debugger to be " +
|
||||
"registered");
|
||||
promise = waitForRegister(SHARED_WORKER_URL);
|
||||
worker = new SharedWorker(SHARED_WORKER_URL);
|
||||
|
@ -94,7 +93,6 @@
|
|||
},
|
||||
};
|
||||
wdm.addListener(listener);
|
||||
|
||||
worker = new SharedWorker(SHARED_WORKER_URL);
|
||||
|
||||
info("Send a message to the shared worker to tell it to close " +
|
||||
|
@ -107,29 +105,6 @@
|
|||
worker.port.postMessage("close");
|
||||
await promise;
|
||||
|
||||
promise = waitForRegister(SHARED_WORKER_URL);
|
||||
worker = new SharedWorker(SHARED_WORKER_URL);
|
||||
sharedDbg = await promise;
|
||||
|
||||
info("Send a message to the shared worker to tell it to close " +
|
||||
"itself, then loop forever, and wait for its debugger to be closed.");
|
||||
promise = waitForMultiple([
|
||||
waitForUnregister(SHARED_WORKER_URL),
|
||||
waitForDebuggerClose(sharedDbg)
|
||||
]);
|
||||
|
||||
// When the closing process begins, we schedule a timer to terminate
|
||||
// the worker in case it's in an infinite loop, which is exactly what
|
||||
// we do in this test. We want a duration long enough that we can be
|
||||
// confident that the infinite loop was entered as measured by
|
||||
// performance.now() and that we terminated it, but not as long as our
|
||||
// 30 second default we currently ship.
|
||||
await SpecialPowers.pushPrefEnv({"set": [[ "dom.worker.canceling.timeoutMilliseconds", 15000 ]]});
|
||||
|
||||
worker.port.start();
|
||||
worker.port.postMessage("close_loop");
|
||||
await promise;
|
||||
|
||||
wdm.removeListener(listener);
|
||||
SimpleTest.finish();
|
||||
})();
|
||||
|
|
|
@ -4958,12 +4958,6 @@ Preferences::AddAtomicUintVarCache(Atomic<uint32_t, ReleaseAcquire>*,
|
|||
uint32_t,
|
||||
bool);
|
||||
|
||||
template nsresult
|
||||
Preferences::AddAtomicUintVarCache(Atomic<uint32_t, SequentiallyConsistent>*,
|
||||
const char*,
|
||||
uint32_t,
|
||||
bool);
|
||||
|
||||
static void
|
||||
FloatVarChanged(const char* aPref, void* aClosure)
|
||||
{
|
||||
|
|
|
@ -121,21 +121,4 @@ async_test(t => {
|
|||
}
|
||||
}, 'BroadcastChannel created after a worker self.close()');
|
||||
|
||||
async_test(t => {
|
||||
function workerCode() {
|
||||
close();
|
||||
var bc = new BroadcastChannel('worker-test-after-close');
|
||||
bc.postMessage(true);
|
||||
}
|
||||
|
||||
var bc = new BroadcastChannel('worker-test-after-close');
|
||||
bc.onmessage = function(e) {
|
||||
assert_true(e.data, "BroadcastChannel created on worker shutdown.");
|
||||
t.done();
|
||||
}
|
||||
|
||||
var workerBlob = new Blob([workerCode.toString() + ";workerCode();"], {type:"application/javascript"});
|
||||
new Worker(URL.createObjectURL(workerBlob));
|
||||
}, 'BroadcastChannel used after a worker self.close()');
|
||||
|
||||
</script>
|
||||
|
|
Загрузка…
Ссылка в новой задаче