Bug 1660307 - Get rid off nsSupportsWeakReference for WebSocketImpl, r=baku
Differential Revision: https://phabricator.services.mozilla.com/D111059
This commit is contained in:
@@ -29,6 +29,7 @@
|
|||||||
#include "mozilla/dom/WorkerRef.h"
|
#include "mozilla/dom/WorkerRef.h"
|
||||||
#include "mozilla/dom/WorkerRunnable.h"
|
#include "mozilla/dom/WorkerRunnable.h"
|
||||||
#include "mozilla/dom/WorkerScope.h"
|
#include "mozilla/dom/WorkerScope.h"
|
||||||
|
#include "mozilla/ScopeExit.h"
|
||||||
#include "mozilla/StaticPrefs_dom.h"
|
#include "mozilla/StaticPrefs_dom.h"
|
||||||
#include "mozilla/LoadInfo.h"
|
#include "mozilla/LoadInfo.h"
|
||||||
#include "nsGlobalWindow.h"
|
#include "nsGlobalWindow.h"
|
||||||
@@ -80,10 +81,38 @@ using namespace mozilla::net;
|
|||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
|
class WebSocketImpl;
|
||||||
|
|
||||||
|
// This class is responsible for proxying nsIObserver and nsIWebSocketImpl
|
||||||
|
// interfaces to WebSocketImpl. WebSocketImplProxy should be only accessed on
|
||||||
|
// main thread, so we can let it support weak reference.
|
||||||
|
class WebSocketImplProxy final : public nsIObserver,
|
||||||
|
public nsSupportsWeakReference,
|
||||||
|
public nsIWebSocketImpl {
|
||||||
|
public:
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_DECL_NSIOBSERVER
|
||||||
|
NS_DECL_NSIWEBSOCKETIMPL
|
||||||
|
|
||||||
|
explicit WebSocketImplProxy(WebSocketImpl* aOwner) : mOwner(aOwner) {
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Disconnect() {
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
mOwner = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
~WebSocketImplProxy() = default;
|
||||||
|
|
||||||
|
RefPtr<WebSocketImpl> mOwner;
|
||||||
|
};
|
||||||
|
|
||||||
class WebSocketImpl final : public nsIInterfaceRequestor,
|
class WebSocketImpl final : public nsIInterfaceRequestor,
|
||||||
public nsIWebSocketListener,
|
public nsIWebSocketListener,
|
||||||
public nsIObserver,
|
public nsIObserver,
|
||||||
public nsSupportsWeakReference,
|
|
||||||
public nsIRequest,
|
public nsIRequest,
|
||||||
public nsIEventTarget,
|
public nsIEventTarget,
|
||||||
public nsIWebSocketImpl {
|
public nsIWebSocketImpl {
|
||||||
@@ -116,6 +145,8 @@ class WebSocketImpl final : public nsIInterfaceRequestor,
|
|||||||
mWorkerShuttingDown(false) {
|
mWorkerShuttingDown(false) {
|
||||||
if (!NS_IsMainThread()) {
|
if (!NS_IsMainThread()) {
|
||||||
mIsMainThread = false;
|
mIsMainThread = false;
|
||||||
|
} else {
|
||||||
|
mImplProxy = new WebSocketImplProxy(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,6 +261,8 @@ class WebSocketImpl final : public nsIInterfaceRequestor,
|
|||||||
// For dispatching runnables to main thread.
|
// For dispatching runnables to main thread.
|
||||||
nsCOMPtr<nsIEventTarget> mMainThreadEventTarget;
|
nsCOMPtr<nsIEventTarget> mMainThreadEventTarget;
|
||||||
|
|
||||||
|
RefPtr<WebSocketImplProxy> mImplProxy;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
~WebSocketImpl() {
|
~WebSocketImpl() {
|
||||||
MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread() == mIsMainThread ||
|
MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread() == mIsMainThread ||
|
||||||
@@ -242,9 +275,30 @@ class WebSocketImpl final : public nsIInterfaceRequestor,
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS(WebSocketImplProxy, nsIObserver, nsISupportsWeakReference,
|
||||||
|
nsIWebSocketImpl)
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
WebSocketImplProxy::Observe(nsISupports* aSubject, const char* aTopic,
|
||||||
|
const char16_t* aData) {
|
||||||
|
if (!mOwner) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mOwner->Observe(aSubject, aTopic, aData);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
WebSocketImplProxy::SendMessage(const nsAString& aMessage) {
|
||||||
|
if (!mOwner) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mOwner->SendMessage(aMessage);
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(WebSocketImpl, nsIInterfaceRequestor, nsIWebSocketListener,
|
NS_IMPL_ISUPPORTS(WebSocketImpl, nsIInterfaceRequestor, nsIWebSocketListener,
|
||||||
nsIObserver, nsISupportsWeakReference, nsIRequest,
|
nsIObserver, nsIRequest, nsIEventTarget, nsIWebSocketImpl)
|
||||||
nsIEventTarget, nsIWebSocketImpl)
|
|
||||||
|
|
||||||
class CallDispatchConnectionCloseEvents final : public DiscardableRunnable {
|
class CallDispatchConnectionCloseEvents final : public DiscardableRunnable {
|
||||||
public:
|
public:
|
||||||
@@ -617,6 +671,11 @@ void WebSocketImpl::DisconnectInternal() {
|
|||||||
os->RemoveObserver(this, DOM_WINDOW_FROZEN_TOPIC);
|
os->RemoveObserver(this, DOM_WINDOW_FROZEN_TOPIC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mImplProxy) {
|
||||||
|
mImplProxy->Disconnect();
|
||||||
|
mImplProxy = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -1248,6 +1307,12 @@ already_AddRefed<WebSocket> WebSocket::ConstructorCommon(
|
|||||||
RefPtr<WebSocket> webSocket = new WebSocket(global);
|
RefPtr<WebSocket> webSocket = new WebSocket(global);
|
||||||
RefPtr<WebSocketImpl> webSocketImpl = webSocket->mImpl;
|
RefPtr<WebSocketImpl> webSocketImpl = webSocket->mImpl;
|
||||||
|
|
||||||
|
auto clearGuard = MakeScopeExit([&] {
|
||||||
|
if (NS_IsMainThread()) {
|
||||||
|
webSocketImpl->mImplProxy->Disconnect();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
bool connectionFailed = true;
|
bool connectionFailed = true;
|
||||||
|
|
||||||
if (NS_IsMainThread()) {
|
if (NS_IsMainThread()) {
|
||||||
@@ -1492,11 +1557,12 @@ nsresult WebSocketImpl::Init(JSContext* aCx, nsIPrincipal* aLoadingPrincipal,
|
|||||||
if (NS_WARN_IF(!os)) {
|
if (NS_WARN_IF(!os)) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
MOZ_ASSERT(mImplProxy);
|
||||||
|
|
||||||
rv = os->AddObserver(this, DOM_WINDOW_DESTROYED_TOPIC, true);
|
rv = os->AddObserver(mImplProxy, DOM_WINDOW_DESTROYED_TOPIC, true);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
rv = os->AddObserver(this, DOM_WINDOW_FROZEN_TOPIC, true);
|
rv = os->AddObserver(mImplProxy, DOM_WINDOW_FROZEN_TOPIC, true);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1781,7 +1847,9 @@ nsresult WebSocketImpl::InitializeConnection(
|
|||||||
mChannel = wsChannel;
|
mChannel = wsChannel;
|
||||||
|
|
||||||
if (mIsMainThread) {
|
if (mIsMainThread) {
|
||||||
mService->AssociateWebSocketImplWithSerialID(this, mChannel->Serial());
|
MOZ_ASSERT(mImplProxy);
|
||||||
|
mService->AssociateWebSocketImplWithSerialID(mImplProxy,
|
||||||
|
mChannel->Serial());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mIsMainThread && doc) {
|
if (mIsMainThread && doc) {
|
||||||
|
|||||||
Reference in New Issue
Block a user