diff --git a/dom/websocket/WebSocket.cpp b/dom/websocket/WebSocket.cpp index d822d7a6f62c..0d88b80e5193 100644 --- a/dom/websocket/WebSocket.cpp +++ b/dom/websocket/WebSocket.cpp @@ -231,9 +231,42 @@ class WebSocketImpl final : public nsIInterfaceRequestor, } }; -NS_IMPL_ISUPPORTS(WebSocketImpl, nsIInterfaceRequestor, nsIWebSocketListener, - nsIObserver, nsISupportsWeakReference, nsIRequest, - nsIEventTarget) +NS_IMPL_ADDREF(WebSocketImpl) +NS_IMPL_QUERY_INTERFACE(WebSocketImpl, nsIInterfaceRequestor, + nsIWebSocketListener, nsIObserver, + nsISupportsWeakReference, nsIRequest, nsIEventTarget) + +NS_IMETHODIMP_(MozExternalRefCountType) WebSocketImpl::Release(void) { + MOZ_ASSERT(int32_t(mRefCnt) > 0, "dup release"); + + if (!mRefCnt.isThreadSafe) { + NS_ASSERT_OWNINGTHREAD(WebSocketImpl); + } + + nsrefcnt count = mRefCnt - 1; + // Make sure the last release of WebSocketImpl is on the right thread. + if (count == 0 && !IsTargetThread()) { + Dispatch(NewNonOwningRunnableMethod("dom::WebSocketImpl::Release", this, + &WebSocketImpl::Release)); + return count; + } + + count = --mRefCnt; + NS_LOG_RELEASE(this, count, "WebSocketImpl"); + + if (count == 0) { + AssertIsOnTargetThread(); + + if (!mRefCnt.isThreadSafe) { + NS_ASSERT_OWNINGTHREAD(WebSocketImpl); + } + + mRefCnt = 1; /* stabilize */ + delete (this); + return 0; + } + return count; +} class CallDispatchConnectionCloseEvents final : public CancelableRunnable { public: