Issue #1767 - Prevent incorrect calling of network change detection function.

This rewrites the websocket channel network change detection function to not
skip part of its logic in a situation that has already been checked, preventing
a thread race. See analysis of the problem in the issue.
This commit is contained in:
Moonchild
2021-04-26 10:26:22 +00:00
parent 5e705bd505
commit 4e31a42b28
2 changed files with 16 additions and 13 deletions
+15 -13
View File
@@ -1247,10 +1247,10 @@ WebSocketChannel::Observe(nsISupports *subject,
// Next we check mDataStarted, which we need to do on mTargetThread.
if (!IsOnTargetThread()) {
mTargetThread->Dispatch(
NewRunnableMethod(this, &WebSocketChannel::OnNetworkChanged),
NewRunnableMethod(this, &WebSocketChannel::OnNetworkChangedTargetThread),
NS_DISPATCH_NORMAL);
} else {
OnNetworkChanged();
OnNetworkChangedTargetThread();
}
}
}
@@ -1260,21 +1260,23 @@ WebSocketChannel::Observe(nsISupports *subject,
}
nsresult
WebSocketChannel::OnNetworkChanged()
WebSocketChannel::OnNetworkChangedTargetThread()
{
if (IsOnTargetThread()) {
LOG(("WebSocketChannel::OnNetworkChanged() - on target thread %p", this));
LOG(("WebSocketChannel::OnNetworkChangedTargetThread() - on target thread %p", this));
if (!mDataStarted) {
LOG(("WebSocket: data not started yet, no ping needed"));
return NS_OK;
}
return mSocketThread->Dispatch(
NewRunnableMethod(this, &WebSocketChannel::OnNetworkChanged),
NS_DISPATCH_NORMAL);
if (!mDataStarted) {
LOG(("WebSocket: data not started yet, no ping needed"));
return NS_OK;
}
return mSocketThread->Dispatch(
NewRunnableMethod(this, &WebSocketChannel::OnNetworkChanged),
NS_DISPATCH_NORMAL);
}
nsresult
WebSocketChannel::OnNetworkChanged()
{
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread, "not socket thread");
LOG(("WebSocketChannel::OnNetworkChanged() - on socket thread %p", this));
@@ -146,6 +146,7 @@ private:
void GeneratePong(uint8_t *payload, uint32_t len);
void GeneratePing();
nsresult OnNetworkChangedTargetThread();
nsresult OnNetworkChanged();
nsresult StartPinging();