зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1152334 - StartWebsocketData null deref mSocketIn, r=bagder
This commit is contained in:
Родитель
918442bd01
Коммит
b34c97d19b
|
@ -1223,39 +1223,78 @@ WebSocketChannel::Observe(nsISupports *subject,
|
|||
|
||||
if (strcmp(state, NS_NETWORK_LINK_DATA_CHANGED) == 0) {
|
||||
LOG(("WebSocket: received network CHANGED event"));
|
||||
if (mPingOutstanding) {
|
||||
// If there's an outstanding ping that's expected to get a pong back
|
||||
// we let that do its thing.
|
||||
LOG(("WebSocket: pong already pending"));
|
||||
} else if (!mSocketThread) {
|
||||
|
||||
if (!mSocketThread) {
|
||||
// there has not been an asyncopen yet on the object and then we need
|
||||
// no ping.
|
||||
LOG(("WebSocket: early object, no ping needed"));
|
||||
} else {
|
||||
LOG(("nsWebSocketChannel:: Generating Ping as network changed\n"));
|
||||
|
||||
if (mPingForced) {
|
||||
// avoid more than one
|
||||
return NS_OK;
|
||||
// Next we check mDataStarted, which we need to do on mTargetThread.
|
||||
if (!IsOnTargetThread()) {
|
||||
mTargetThread->Dispatch(
|
||||
NS_NewRunnableMethod(this, &WebSocketChannel::OnNetworkChanged),
|
||||
NS_DISPATCH_NORMAL);
|
||||
} else {
|
||||
OnNetworkChanged();
|
||||
}
|
||||
if (!mPingTimer) {
|
||||
// The ping timer is only conditionally running already. If it
|
||||
// wasn't already created do it here.
|
||||
nsresult rv;
|
||||
mPingTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("unable to create ping timer. Carrying on.");
|
||||
} else {
|
||||
mPingTimer->SetTarget(mSocketThread);
|
||||
}
|
||||
}
|
||||
// Trigger the ping timeout asap to fire off a new ping. Wait just
|
||||
// a little bit to better avoid multi-triggers.
|
||||
mPingForced = 1;
|
||||
mPingTimer->InitWithCallback(this, 200, nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
WebSocketChannel::OnNetworkChanged()
|
||||
{
|
||||
if (IsOnTargetThread()) {
|
||||
LOG(("WebSocketChannel::OnNetworkChanged() - on target thread %p", this));
|
||||
|
||||
if (!mDataStarted) {
|
||||
LOG(("WebSocket: data not started yet, no ping needed"));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return mSocketThread->Dispatch(
|
||||
NS_NewRunnableMethod(this, &WebSocketChannel::OnNetworkChanged),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread, "not socket thread");
|
||||
|
||||
LOG(("WebSocketChannel::OnNetworkChanged() - on socket thread %p", this));
|
||||
|
||||
if (mPingOutstanding) {
|
||||
// If there's an outstanding ping that's expected to get a pong back
|
||||
// we let that do its thing.
|
||||
LOG(("WebSocket: pong already pending"));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mPingForced) {
|
||||
// avoid more than one
|
||||
LOG(("WebSocket: forced ping timer already fired"));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
LOG(("nsWebSocketChannel:: Generating Ping as network changed\n"));
|
||||
|
||||
if (!mPingTimer) {
|
||||
// The ping timer is only conditionally running already. If it wasn't
|
||||
// already created do it here.
|
||||
nsresult rv;
|
||||
mPingTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("WebSocket: unable to create ping timer!"));
|
||||
NS_WARNING("unable to create ping timer!");
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
// Trigger the ping timeout asap to fire off a new ping. Wait just
|
||||
// a little bit to better avoid multi-triggers.
|
||||
mPingForced = 1;
|
||||
mPingTimer->InitWithCallback(this, 200, nsITimer::TYPE_ONE_SHOT);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2574,6 +2613,8 @@ WebSocketChannel::ApplyForAdmission()
|
|||
nsresult
|
||||
WebSocketChannel::StartWebsocketData()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (!IsOnTargetThread()) {
|
||||
return mTargetThread->Dispatch(
|
||||
NS_NewRunnableMethod(this, &WebSocketChannel::StartWebsocketData),
|
||||
|
@ -2596,23 +2637,47 @@ WebSocketChannel::StartWebsocketData()
|
|||
mListenerMT->mListener->OnStart(mListenerMT->mContext);
|
||||
}
|
||||
|
||||
// Start keepalive ping timer, if we're using keepalive.
|
||||
rv = mSocketIn->AsyncWait(this, 0, 0, mSocketThread);
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("WebSocketChannel::StartWebsocketData mSocketIn->AsyncWait() failed "
|
||||
"with error %0x%08x\n", rv));
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (mPingInterval) {
|
||||
nsresult rv;
|
||||
mPingTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
|
||||
rv = mSocketThread->Dispatch(
|
||||
NS_NewRunnableMethod(this, &WebSocketChannel::StartPinging),
|
||||
NS_DISPATCH_NORMAL);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("unable to create ping timer. Carrying on.");
|
||||
} else {
|
||||
LOG(("WebSocketChannel will generate ping after %d ms of receive silence\n",
|
||||
mPingInterval));
|
||||
mPingTimer->SetTarget(mSocketThread);
|
||||
mPingTimer->InitWithCallback(this, mPingInterval, nsITimer::TYPE_ONE_SHOT);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
return mSocketIn->AsyncWait(this, 0, 0, mSocketThread);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
WebSocketChannel::StartPinging()
|
||||
{
|
||||
LOG(("WebSocketChannel::StartPinging() %p", this));
|
||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread, "not socket thread");
|
||||
MOZ_ASSERT(mPingInterval);
|
||||
MOZ_ASSERT(!mPingTimer);
|
||||
|
||||
nsresult rv;
|
||||
mPingTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("unable to create ping timer. Carrying on.");
|
||||
} else {
|
||||
LOG(("WebSocketChannel will generate ping after %d ms of receive silence\n",
|
||||
mPingInterval));
|
||||
mPingTimer->InitWithCallback(this, mPingInterval, nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WebSocketChannel::ReportConnectionTelemetry()
|
||||
{
|
||||
|
|
|
@ -144,6 +144,9 @@ private:
|
|||
void GeneratePong(uint8_t *payload, uint32_t len);
|
||||
void GeneratePing();
|
||||
|
||||
nsresult OnNetworkChanged();
|
||||
nsresult StartPinging();
|
||||
|
||||
void BeginOpen();
|
||||
nsresult HandleExtensions();
|
||||
nsresult SetupRequest();
|
||||
|
|
Загрузка…
Ссылка в новой задаче