зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1333112 - Fix windowClient.Navigate leak. r=bkelly
This commit is contained in:
Родитель
d1775338ca
Коммит
d766bfbd2b
|
@ -825,16 +825,6 @@ PromiseWorkerProxy::WorkerPromise() const
|
|||
return mWorkerPromise;
|
||||
}
|
||||
|
||||
void
|
||||
PromiseWorkerProxy::StoreISupports(nsISupports* aSupports)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsMainThreadPtrHandle<nsISupports> supports(
|
||||
new nsMainThreadPtrHolder<nsISupports>(aSupports));
|
||||
mSupportsArray.AppendElement(supports);
|
||||
}
|
||||
|
||||
void
|
||||
PromiseWorkerProxy::RunCallback(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aValue,
|
||||
|
|
|
@ -147,8 +147,6 @@ public:
|
|||
// worker thread! Do not call this after calling CleanUp().
|
||||
Promise* WorkerPromise() const;
|
||||
|
||||
void StoreISupports(nsISupports* aSupports);
|
||||
|
||||
// Worker thread only. Calling this invalidates several assumptions, so be
|
||||
// sure this is the last thing you do.
|
||||
// 1. WorkerPrivate() will no longer return a valid worker.
|
||||
|
@ -217,10 +215,6 @@ private:
|
|||
|
||||
const PromiseWorkerProxyStructuredCloneCallbacks* mCallbacks;
|
||||
|
||||
// Aimed to keep objects alive when doing the structured-clone read/write,
|
||||
// which can be added by calling StoreISupports() on the main thread.
|
||||
nsTArray<nsMainThreadPtrHandle<nsISupports>> mSupportsArray;
|
||||
|
||||
// Ensure the worker and the main thread won't race to access |mCleanedUp|.
|
||||
Mutex mCleanUpLock;
|
||||
|
||||
|
|
|
@ -204,18 +204,21 @@ public:
|
|||
nsIWebProgressListener)
|
||||
|
||||
WebProgressListener(PromiseWorkerProxy* aPromiseProxy,
|
||||
ServiceWorkerPrivate* aServiceWorkerPrivate,
|
||||
nsPIDOMWindowOuter* aWindow, nsIURI* aBaseURI)
|
||||
: mPromiseProxy(aPromiseProxy)
|
||||
, mServiceWorkerPrivate(aServiceWorkerPrivate)
|
||||
, mWindow(aWindow)
|
||||
, mBaseURI(aBaseURI)
|
||||
{
|
||||
MOZ_ASSERT(aPromiseProxy);
|
||||
MOZ_ASSERT(aServiceWorkerPrivate);
|
||||
MOZ_ASSERT(aWindow);
|
||||
MOZ_ASSERT(aWindow->IsOuterWindow());
|
||||
MOZ_ASSERT(aBaseURI);
|
||||
AssertIsOnMainThread();
|
||||
|
||||
mPromiseProxy->StoreISupports(static_cast<nsIWebProgressListener*>(this));
|
||||
mServiceWorkerPrivate->StoreISupports(static_cast<nsIWebProgressListener*>(this));
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
|
@ -227,6 +230,8 @@ public:
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// This is safe because our caller holds a strong ref.
|
||||
mServiceWorkerPrivate->RemoveISupports(static_cast<nsIWebProgressListener*>(this));
|
||||
aWebProgress->RemoveProgressListener(this);
|
||||
|
||||
WorkerPrivate* workerPrivate;
|
||||
|
@ -308,6 +313,7 @@ private:
|
|||
~WebProgressListener() {}
|
||||
|
||||
RefPtr<PromiseWorkerProxy> mPromiseProxy;
|
||||
RefPtr<ServiceWorkerPrivate> mServiceWorkerPrivate;
|
||||
nsCOMPtr<nsPIDOMWindowOuter> mWindow;
|
||||
nsCOMPtr<nsIURI> mBaseURI;
|
||||
};
|
||||
|
@ -315,7 +321,7 @@ private:
|
|||
NS_IMPL_CYCLE_COLLECTING_ADDREF(WebProgressListener)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(WebProgressListener)
|
||||
NS_IMPL_CYCLE_COLLECTION(WebProgressListener, mPromiseProxy,
|
||||
mWindow)
|
||||
mServiceWorkerPrivate, mWindow)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebProgressListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
|
||||
|
@ -327,14 +333,17 @@ class ClientNavigateRunnable final : public Runnable
|
|||
uint64_t mWindowId;
|
||||
nsString mUrl;
|
||||
nsCString mBaseUrl;
|
||||
nsString mScope;
|
||||
RefPtr<PromiseWorkerProxy> mPromiseProxy;
|
||||
MOZ_INIT_OUTSIDE_CTOR WorkerPrivate* mWorkerPrivate;
|
||||
|
||||
public:
|
||||
ClientNavigateRunnable(uint64_t aWindowId, const nsAString& aUrl,
|
||||
const nsAString& aScope,
|
||||
PromiseWorkerProxy* aPromiseProxy)
|
||||
: mWindowId(aWindowId)
|
||||
, mUrl(aUrl)
|
||||
, mScope(aScope)
|
||||
, mPromiseProxy(aPromiseProxy)
|
||||
, mWorkerPrivate(nullptr)
|
||||
{
|
||||
|
@ -360,6 +369,7 @@ public:
|
|||
WorkerPrivate::LocationInfo& info = mWorkerPrivate->GetLocationInfo();
|
||||
mBaseUrl = info.mHref;
|
||||
principal = mWorkerPrivate->GetPrincipal();
|
||||
MOZ_DIAGNOSTIC_ASSERT(principal);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> baseUrl;
|
||||
|
@ -387,8 +397,25 @@ public:
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
if (!swm) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
RefPtr<ServiceWorkerRegistrationInfo> registration =
|
||||
swm->GetRegistration(principal, NS_ConvertUTF16toUTF8(mScope));
|
||||
if (NS_WARN_IF(!registration)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
RefPtr<ServiceWorkerInfo> serviceWorkerInfo =
|
||||
registration->GetServiceWorkerInfoById(mWorkerPrivate->ServiceWorkerID());
|
||||
if (NS_WARN_IF(!serviceWorkerInfo)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWebProgressListener> listener =
|
||||
new WebProgressListener(mPromiseProxy, window->GetOuterWindow(), baseUrl);
|
||||
new WebProgressListener(mPromiseProxy, serviceWorkerInfo->WorkerPrivate(),
|
||||
window->GetOuterWindow(), baseUrl);
|
||||
|
||||
rv = webProgress->AddProgressListener(
|
||||
listener, nsIWebProgress::NOTIFY_STATE_DOCUMENT);
|
||||
|
@ -512,11 +539,16 @@ ServiceWorkerWindowClient::Navigate(const nsAString& aUrl, ErrorResult& aRv)
|
|||
return promise.forget();
|
||||
}
|
||||
|
||||
ServiceWorkerGlobalScope* globalScope =
|
||||
static_cast<ServiceWorkerGlobalScope*>(workerPrivate->GlobalScope());
|
||||
nsString scope;
|
||||
globalScope->GetScope(scope);
|
||||
|
||||
RefPtr<PromiseWorkerProxy> promiseProxy =
|
||||
PromiseWorkerProxy::Create(workerPrivate, promise);
|
||||
if (promiseProxy) {
|
||||
RefPtr<ClientNavigateRunnable> r =
|
||||
new ClientNavigateRunnable(mWindowId, aUrl, promiseProxy);
|
||||
new ClientNavigateRunnable(mWindowId, aUrl, scope, promiseProxy);
|
||||
MOZ_ALWAYS_SUCCEEDS(workerPrivate->DispatchToMainThread(r.forget()));
|
||||
} else {
|
||||
promise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
|
||||
|
|
Загрузка…
Ссылка в новой задаче