зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
d1557a6f2b
Коммит
3e07310481
|
@ -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:
|
||||
|
|
Загрузка…
Ссылка в новой задаче