mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1190672 - Fix use of AutoReleasePromiseWorkerProxy in PushManager. r=catalinb
This commit is contained in:
parent
eff4fc7c12
commit
163db26016
@ -215,38 +215,29 @@ WorkerPushSubscription::Constructor(GlobalObject& aGlobal, const nsAString& aEnd
|
|||||||
return sub.forget();
|
return sub.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
class MOZ_STACK_CLASS AutoReleasePromiseWorkerProxy final
|
namespace {
|
||||||
|
// The caller MUST take ownership of the proxy's lock before it calls this.
|
||||||
|
void
|
||||||
|
ReleasePromiseWorkerProxy(already_AddRefed<PromiseWorkerProxy> aProxy)
|
||||||
{
|
{
|
||||||
public:
|
AssertIsOnMainThread();
|
||||||
explicit AutoReleasePromiseWorkerProxy(PromiseWorkerProxy* aProxy)
|
nsRefPtr<PromiseWorkerProxy> proxy = aProxy;
|
||||||
: mProxy(aProxy)
|
MOZ_ASSERT(proxy);
|
||||||
{
|
proxy->GetCleanUpLock().AssertCurrentThreadOwns();
|
||||||
AssertIsOnMainThread();
|
if (proxy->IsClean()) {
|
||||||
MOZ_ASSERT(aProxy);
|
return;
|
||||||
aProxy->GetCleanUpLock().AssertCurrentThreadOwns();
|
|
||||||
if (aProxy->IsClean()) {
|
|
||||||
mProxy = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~AutoReleasePromiseWorkerProxy()
|
AutoJSAPI jsapi;
|
||||||
{
|
jsapi.Init();
|
||||||
if (mProxy) {
|
|
||||||
AutoJSAPI jsapi;
|
|
||||||
jsapi.Init();
|
|
||||||
|
|
||||||
nsRefPtr<PromiseWorkerProxyControlRunnable> cr =
|
nsRefPtr<PromiseWorkerProxyControlRunnable> cr =
|
||||||
new PromiseWorkerProxyControlRunnable(mProxy->GetWorkerPrivate(),
|
new PromiseWorkerProxyControlRunnable(proxy->GetWorkerPrivate(),
|
||||||
mProxy);
|
proxy);
|
||||||
|
|
||||||
DebugOnly<bool> ok = cr->Dispatch(jsapi.cx());
|
MOZ_ALWAYS_TRUE(cr->Dispatch(jsapi.cx()));
|
||||||
MOZ_ASSERT(ok);
|
}
|
||||||
mProxy = nullptr;
|
} // anonymous namespace
|
||||||
}
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
nsRefPtr<PromiseWorkerProxy> mProxy;
|
|
||||||
};
|
|
||||||
|
|
||||||
class UnsubscribeResultRunnable final : public WorkerRunnable
|
class UnsubscribeResultRunnable final : public WorkerRunnable
|
||||||
{
|
{
|
||||||
@ -281,12 +272,7 @@ public:
|
|||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
~UnsubscribeResultRunnable()
|
~UnsubscribeResultRunnable()
|
||||||
{
|
{}
|
||||||
if (mProxy) {
|
|
||||||
AutoReleasePromiseWorkerProxy autoRelease(mProxy);
|
|
||||||
mProxy = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<PromiseWorkerProxy> mProxy;
|
nsRefPtr<PromiseWorkerProxy> mProxy;
|
||||||
nsresult mStatus;
|
nsresult mStatus;
|
||||||
@ -300,6 +286,7 @@ public:
|
|||||||
|
|
||||||
explicit WorkerUnsubscribeResultCallback(PromiseWorkerProxy* aProxy)
|
explicit WorkerUnsubscribeResultCallback(PromiseWorkerProxy* aProxy)
|
||||||
: mProxy(aProxy)
|
: mProxy(aProxy)
|
||||||
|
, mCallbackCalled(false)
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
}
|
}
|
||||||
@ -308,6 +295,7 @@ public:
|
|||||||
OnUnsubscribe(nsresult aStatus, bool aSuccess) override
|
OnUnsubscribe(nsresult aStatus, bool aSuccess) override
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
|
mCallbackCalled = true;
|
||||||
if (!mProxy) {
|
if (!mProxy) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -322,22 +310,23 @@ public:
|
|||||||
|
|
||||||
nsRefPtr<UnsubscribeResultRunnable> r =
|
nsRefPtr<UnsubscribeResultRunnable> r =
|
||||||
new UnsubscribeResultRunnable(mProxy, aStatus, aSuccess);
|
new UnsubscribeResultRunnable(mProxy, aStatus, aSuccess);
|
||||||
mProxy = nullptr;
|
if (!r->Dispatch(jsapi.cx())) {
|
||||||
|
ReleasePromiseWorkerProxy(mProxy.forget());
|
||||||
|
}
|
||||||
|
|
||||||
r->Dispatch(jsapi.cx());
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
~WorkerUnsubscribeResultCallback()
|
~WorkerUnsubscribeResultCallback()
|
||||||
{
|
{
|
||||||
if (mProxy) {
|
// Enforces that UnsubscribeRunnable uses the callback for error
|
||||||
AutoReleasePromiseWorkerProxy autoRelease(mProxy);
|
// reporting once it creates the callback.
|
||||||
mProxy = nullptr;
|
MOZ_ASSERT(mCallbackCalled);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<PromiseWorkerProxy> mProxy;
|
nsRefPtr<PromiseWorkerProxy> mProxy;
|
||||||
|
DebugOnly<bool> mCallbackCalled;
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(WorkerUnsubscribeResultCallback, nsIUnsubscribeResultCallback)
|
NS_IMPL_ISUPPORTS(WorkerUnsubscribeResultCallback, nsIUnsubscribeResultCallback)
|
||||||
@ -363,36 +352,27 @@ public:
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsRefPtr<WorkerUnsubscribeResultCallback> callback =
|
||||||
|
new WorkerUnsubscribeResultCallback(mProxy);
|
||||||
|
|
||||||
nsCOMPtr<nsIPushClient> client =
|
nsCOMPtr<nsIPushClient> client =
|
||||||
do_CreateInstance("@mozilla.org/push/PushClient;1");
|
do_CreateInstance("@mozilla.org/push/PushClient;1");
|
||||||
if (!client) {
|
if (!client) {
|
||||||
AutoJSAPI jsapi;
|
callback->OnUnsubscribe(NS_ERROR_FAILURE, false);
|
||||||
jsapi.Init();
|
|
||||||
|
|
||||||
nsRefPtr<UnsubscribeResultRunnable> r =
|
|
||||||
new UnsubscribeResultRunnable(mProxy, NS_ERROR_FAILURE, false);
|
|
||||||
mProxy = nullptr;
|
|
||||||
|
|
||||||
r->Dispatch(jsapi.cx());
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIPrincipal> principal = mProxy->GetWorkerPrivate()->GetPrincipal();
|
nsCOMPtr<nsIPrincipal> principal = mProxy->GetWorkerPrivate()->GetPrincipal();
|
||||||
nsRefPtr<WorkerUnsubscribeResultCallback> callback =
|
if (NS_WARN_IF(NS_FAILED(client->Unsubscribe(mScope, principal, callback)))) {
|
||||||
new WorkerUnsubscribeResultCallback(mProxy);
|
callback->OnUnsubscribe(NS_ERROR_FAILURE, false);
|
||||||
mProxy = nullptr;
|
return NS_ERROR_FAILURE;
|
||||||
client->Unsubscribe(mScope, principal, callback);
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
~UnsubscribeRunnable()
|
~UnsubscribeRunnable()
|
||||||
{
|
{}
|
||||||
if (mProxy) {
|
|
||||||
AutoReleasePromiseWorkerProxy autoRelease(mProxy);
|
|
||||||
mProxy = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nsRefPtr<PromiseWorkerProxy> mProxy;
|
nsRefPtr<PromiseWorkerProxy> mProxy;
|
||||||
nsString mScope;
|
nsString mScope;
|
||||||
};
|
};
|
||||||
@ -418,7 +398,7 @@ WorkerPushSubscription::Unsubscribe(ErrorResult &aRv)
|
|||||||
|
|
||||||
nsRefPtr<UnsubscribeRunnable> r =
|
nsRefPtr<UnsubscribeRunnable> r =
|
||||||
new UnsubscribeRunnable(proxy, mScope);
|
new UnsubscribeRunnable(proxy, mScope);
|
||||||
NS_DispatchToMainThread(r);
|
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(r)));
|
||||||
|
|
||||||
return p.forget();
|
return p.forget();
|
||||||
}
|
}
|
||||||
@ -476,12 +456,7 @@ public:
|
|||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
~GetSubscriptionResultRunnable()
|
~GetSubscriptionResultRunnable()
|
||||||
{
|
{}
|
||||||
if (mProxy) {
|
|
||||||
AutoReleasePromiseWorkerProxy autoRelease(mProxy);
|
|
||||||
mProxy = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<PromiseWorkerProxy> mProxy;
|
nsRefPtr<PromiseWorkerProxy> mProxy;
|
||||||
nsresult mStatus;
|
nsresult mStatus;
|
||||||
@ -498,12 +473,15 @@ public:
|
|||||||
const nsAString& aScope)
|
const nsAString& aScope)
|
||||||
: mProxy(aProxy)
|
: mProxy(aProxy)
|
||||||
, mScope(aScope)
|
, mScope(aScope)
|
||||||
|
, mCallbackCalled(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
NS_IMETHOD
|
NS_IMETHOD
|
||||||
OnPushEndpoint(nsresult aStatus, const nsAString& aEndpoint) override
|
OnPushEndpoint(nsresult aStatus, const nsAString& aEndpoint) override
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
|
mCallbackCalled = true;
|
||||||
|
|
||||||
if (!mProxy) {
|
if (!mProxy) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -518,24 +496,24 @@ public:
|
|||||||
|
|
||||||
nsRefPtr<GetSubscriptionResultRunnable> r =
|
nsRefPtr<GetSubscriptionResultRunnable> r =
|
||||||
new GetSubscriptionResultRunnable(mProxy, aStatus, aEndpoint, mScope);
|
new GetSubscriptionResultRunnable(mProxy, aStatus, aEndpoint, mScope);
|
||||||
mProxy = nullptr;
|
if (!r->Dispatch(jsapi.cx())) {
|
||||||
|
ReleasePromiseWorkerProxy(mProxy.forget());
|
||||||
r->Dispatch(jsapi.cx());
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~GetSubscriptionCallback()
|
~GetSubscriptionCallback()
|
||||||
{
|
{
|
||||||
if (mProxy) {
|
// Enforces that GetSubscriptionRunnable uses the callback for error
|
||||||
AutoReleasePromiseWorkerProxy autoRelease(mProxy);
|
// reporting once it creates the callback.
|
||||||
mProxy = nullptr;
|
MOZ_ASSERT(mCallbackCalled);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsRefPtr<PromiseWorkerProxy> mProxy;
|
nsRefPtr<PromiseWorkerProxy> mProxy;
|
||||||
nsString mScope;
|
nsString mScope;
|
||||||
|
DebugOnly<bool> mCallbackCalled;
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(GetSubscriptionCallback, nsIPushEndpointCallback)
|
NS_IMPL_ISUPPORTS(GetSubscriptionCallback, nsIPushEndpointCallback)
|
||||||
@ -559,14 +537,12 @@ public:
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsRefPtr<GetSubscriptionCallback> callback = new GetSubscriptionCallback(mProxy, mScope);
|
||||||
|
|
||||||
nsCOMPtr<nsIPermissionManager> permManager =
|
nsCOMPtr<nsIPermissionManager> permManager =
|
||||||
mozilla::services::GetPermissionManager();
|
mozilla::services::GetPermissionManager();
|
||||||
|
|
||||||
AutoJSAPI jsapi;
|
|
||||||
jsapi.Init();
|
|
||||||
|
|
||||||
if (!permManager) {
|
if (!permManager) {
|
||||||
Fail(jsapi.cx());
|
callback->OnPushEndpoint(NS_ERROR_FAILURE, EmptyString());
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -577,47 +553,38 @@ public:
|
|||||||
&permission);
|
&permission);
|
||||||
|
|
||||||
if (NS_WARN_IF(NS_FAILED(rv)) || permission != nsIPermissionManager::ALLOW_ACTION) {
|
if (NS_WARN_IF(NS_FAILED(rv)) || permission != nsIPermissionManager::ALLOW_ACTION) {
|
||||||
Fail(jsapi.cx());
|
callback->OnPushEndpoint(NS_ERROR_FAILURE, EmptyString());
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIPushClient> client =
|
nsCOMPtr<nsIPushClient> client =
|
||||||
do_CreateInstance("@mozilla.org/push/PushClient;1");
|
do_CreateInstance("@mozilla.org/push/PushClient;1");
|
||||||
if (!client) {
|
if (!client) {
|
||||||
Fail(jsapi.cx());
|
callback->OnPushEndpoint(NS_ERROR_FAILURE, EmptyString());
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIPrincipal> principal = mProxy->GetWorkerPrivate()->GetPrincipal();
|
nsCOMPtr<nsIPrincipal> principal = mProxy->GetWorkerPrivate()->GetPrincipal();
|
||||||
nsRefPtr<GetSubscriptionCallback> callback = new GetSubscriptionCallback(mProxy, mScope);
|
|
||||||
mProxy = nullptr;
|
mProxy = nullptr;
|
||||||
|
|
||||||
if (mAction == WorkerPushManager::SubscribeAction) {
|
if (mAction == WorkerPushManager::SubscribeAction) {
|
||||||
return client->Subscribe(mScope, principal, callback);
|
rv = client->Subscribe(mScope, principal, callback);
|
||||||
} else {
|
} else {
|
||||||
MOZ_ASSERT(mAction == WorkerPushManager::GetSubscriptionAction);
|
MOZ_ASSERT(mAction == WorkerPushManager::GetSubscriptionAction);
|
||||||
return client->GetSubscription(mScope, principal, callback);
|
rv = client->GetSubscription(mScope, principal, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
callback->OnPushEndpoint(NS_ERROR_FAILURE, EmptyString());
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void
|
|
||||||
Fail(JSContext* aCx)
|
|
||||||
{
|
|
||||||
nsRefPtr<GetSubscriptionResultRunnable> r =
|
|
||||||
new GetSubscriptionResultRunnable(mProxy, NS_ERROR_FAILURE, EmptyString(), mScope);
|
|
||||||
mProxy = nullptr;
|
|
||||||
|
|
||||||
r->Dispatch(aCx);
|
|
||||||
}
|
|
||||||
|
|
||||||
~GetSubscriptionRunnable()
|
~GetSubscriptionRunnable()
|
||||||
{
|
{}
|
||||||
if (mProxy) {
|
|
||||||
AutoReleasePromiseWorkerProxy autoRelease(mProxy);
|
|
||||||
mProxy = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<PromiseWorkerProxy> mProxy;
|
nsRefPtr<PromiseWorkerProxy> mProxy;
|
||||||
nsString mScope;
|
nsString mScope;
|
||||||
@ -645,7 +612,7 @@ WorkerPushManager::PerformSubscriptionAction(SubscriptionAction aAction, ErrorRe
|
|||||||
|
|
||||||
nsRefPtr<GetSubscriptionRunnable> r =
|
nsRefPtr<GetSubscriptionRunnable> r =
|
||||||
new GetSubscriptionRunnable(proxy, mScope, aAction);
|
new GetSubscriptionRunnable(proxy, mScope, aAction);
|
||||||
NS_DispatchToMainThread(r);
|
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(r)));
|
||||||
|
|
||||||
return p.forget();
|
return p.forget();
|
||||||
}
|
}
|
||||||
@ -698,12 +665,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
~PermissionResultRunnable()
|
~PermissionResultRunnable()
|
||||||
{
|
{}
|
||||||
if (mProxy) {
|
|
||||||
AutoReleasePromiseWorkerProxy autoRelease(mProxy);
|
|
||||||
mProxy = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<PromiseWorkerProxy> mProxy;
|
nsRefPtr<PromiseWorkerProxy> mProxy;
|
||||||
nsresult mStatus;
|
nsresult mStatus;
|
||||||
@ -729,55 +691,46 @@ public:
|
|||||||
nsCOMPtr<nsIPermissionManager> permManager =
|
nsCOMPtr<nsIPermissionManager> permManager =
|
||||||
mozilla::services::GetPermissionManager();
|
mozilla::services::GetPermissionManager();
|
||||||
|
|
||||||
|
nsresult rv = NS_ERROR_FAILURE;
|
||||||
PushPermissionState state = PushPermissionState::Denied;
|
PushPermissionState state = PushPermissionState::Denied;
|
||||||
|
|
||||||
|
if (permManager) {
|
||||||
|
uint32_t permission = nsIPermissionManager::DENY_ACTION;
|
||||||
|
rv = permManager->TestExactPermissionFromPrincipal(
|
||||||
|
mProxy->GetWorkerPrivate()->GetPrincipal(),
|
||||||
|
"push",
|
||||||
|
&permission);
|
||||||
|
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
switch (permission) {
|
||||||
|
case nsIPermissionManager::ALLOW_ACTION:
|
||||||
|
state = PushPermissionState::Granted;
|
||||||
|
break;
|
||||||
|
case nsIPermissionManager::DENY_ACTION:
|
||||||
|
state = PushPermissionState::Denied;
|
||||||
|
break;
|
||||||
|
case nsIPermissionManager::PROMPT_ACTION:
|
||||||
|
state = PushPermissionState::Prompt;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
MOZ_CRASH("Unexpected case!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AutoJSAPI jsapi;
|
AutoJSAPI jsapi;
|
||||||
jsapi.Init();
|
jsapi.Init();
|
||||||
|
|
||||||
if (!permManager) {
|
|
||||||
nsRefPtr<PermissionResultRunnable> r =
|
|
||||||
new PermissionResultRunnable(mProxy, NS_ERROR_FAILURE, state);
|
|
||||||
mProxy = nullptr;
|
|
||||||
|
|
||||||
r->Dispatch(jsapi.cx());
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t permission = nsIPermissionManager::DENY_ACTION;
|
|
||||||
nsresult rv = permManager->TestExactPermissionFromPrincipal(
|
|
||||||
mProxy->GetWorkerPrivate()->GetPrincipal(),
|
|
||||||
"push",
|
|
||||||
&permission);
|
|
||||||
|
|
||||||
switch (permission) {
|
|
||||||
case nsIPermissionManager::ALLOW_ACTION:
|
|
||||||
state = PushPermissionState::Granted;
|
|
||||||
break;
|
|
||||||
case nsIPermissionManager::DENY_ACTION:
|
|
||||||
state = PushPermissionState::Denied;
|
|
||||||
break;
|
|
||||||
case nsIPermissionManager::PROMPT_ACTION:
|
|
||||||
state = PushPermissionState::Prompt;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
MOZ_CRASH("Unexpected case!");
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<PermissionResultRunnable> r =
|
nsRefPtr<PermissionResultRunnable> r =
|
||||||
new PermissionResultRunnable(mProxy, rv, state);
|
new PermissionResultRunnable(mProxy, rv, state);
|
||||||
mProxy = nullptr;
|
if (!r->Dispatch(jsapi.cx())) {
|
||||||
r->Dispatch(jsapi.cx());
|
ReleasePromiseWorkerProxy(mProxy.forget());
|
||||||
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
~PermissionStateRunnable()
|
~PermissionStateRunnable()
|
||||||
{
|
{}
|
||||||
if (mProxy) {
|
|
||||||
AutoReleasePromiseWorkerProxy autoRelease(mProxy);
|
|
||||||
mProxy = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<PromiseWorkerProxy> mProxy;
|
nsRefPtr<PromiseWorkerProxy> mProxy;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user