Bug 1555322 - Make sure WebSocketImpl is deleted on the right thread r=smaug

I think the root cause of the crash is that WebSocketImpl is not deleted on the target thread. When this happens, there is a race between setting WebSocket::mImpl to nullptr and accessubg mImpl.
If WebSocketImpl is always deleted on the target thread, WebSocketImpl::Disconnect should be called in ~WebSocketImpl when mDisconnectingOrDisconnected is false.
So, this patch checks the ref counter in WebSocketImpl::Release and make sure to delete WebSocketImpl on the right thread.

Differential Revision: https://phabricator.services.mozilla.com/D34320

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Kershaw Chang 2019-06-19 17:24:23 +00:00
Родитель d1557a6f2b
Коммит 3e07310481
1 изменённых файлов: 36 добавлений и 3 удалений

Просмотреть файл

@ -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: