[WebSocketChannel] Change |state_| out of SendClose() to make state transition clearer
BUG=none
Review URL: https://codereview.chromium.org/196223006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@258005 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/net/websockets/websocket_channel.cc b/net/websockets/websocket_channel.cc
index e8122b6b..ed8a92b 100644
--- a/net/websockets/websocket_channel.cc
+++ b/net/websockets/websocket_channel.cc
@@ -395,13 +395,16 @@
// errata 3227 to RFC6455. If the renderer is sending us an invalid code or
// reason it must be malfunctioning in some way, and based on that we
// interpret this as an internal error.
- AllowUnused(SendClose(kWebSocketErrorInternalServerError, ""));
- // |this| may have been deleted.
+ if (SendClose(kWebSocketErrorInternalServerError, "") != CHANNEL_DELETED)
+ state_ = SEND_CLOSED;
return;
}
- AllowUnused(SendClose(
- code, StreamingUtf8Validator::Validate(reason) ? reason : std::string()));
- // |this| may have been deleted.
+ if (SendClose(
+ code,
+ StreamingUtf8Validator::Validate(reason) ? reason : std::string()) ==
+ CHANNEL_DELETED)
+ return;
+ state_ = SEND_CLOSED;
}
void WebSocketChannel::SendAddChannelRequestForTesting(
@@ -520,6 +523,8 @@
if (result != ERR_IO_PENDING) {
if (OnWriteDone(true, result) == CHANNEL_DELETED)
return CHANNEL_DELETED;
+ // OnWriteDone() returns CHANNEL_DELETED on error. Here |state_| is
+ // guaranteed to be the same as before OnWriteDone() call.
}
} while (result == OK && data_being_sent_);
return CHANNEL_ALIVE;
@@ -717,9 +722,10 @@
switch (state_) {
case CONNECTED:
state_ = RECV_CLOSED;
- if (SendClose(code, reason) == // Sets state_ to CLOSE_WAIT
- CHANNEL_DELETED)
+ if (SendClose(code, reason) == CHANNEL_DELETED)
return CHANNEL_DELETED;
+ state_ = CLOSE_WAIT;
+
if (event_interface_->OnClosingHandshake() == CHANNEL_DELETED)
return CHANNEL_DELETED;
received_close_code_ = code;
@@ -821,12 +827,14 @@
size_t size) {
DCHECK(state_ == CONNECTED || state_ == RECV_CLOSED);
DCHECK(stream_);
+
scoped_ptr<WebSocketFrame> frame(new WebSocketFrame(op_code));
WebSocketFrameHeader& header = frame->header;
header.final = fin;
header.masked = true;
header.payload_length = size;
frame->data = buffer;
+
if (data_being_sent_) {
// Either the link to the WebSocket server is saturated, or several messages
// are being sent in a batch.
@@ -837,6 +845,7 @@
data_to_send_next_->AddFrame(frame.Pass());
return CHANNEL_ALIVE;
}
+
data_being_sent_.reset(new SendBuffer);
data_being_sent_->AddFrame(frame.Pass());
return WriteFrames();
@@ -850,8 +859,7 @@
DCHECK_NE(CLOSED, state_);
// TODO(ricea): Logging.
if (state_ == CONNECTED) {
- if (SendClose(code, reason) == // Sets state_ to SEND_CLOSED
- CHANNEL_DELETED)
+ if (SendClose(code, reason) == CHANNEL_DELETED)
return CHANNEL_DELETED;
}
// Careful study of RFC6455 section 7.1.7 and 7.1.1 indicates the browser
@@ -893,9 +901,6 @@
if (SendIOBuffer(true, WebSocketFrameHeader::kOpCodeClose, body, size) ==
CHANNEL_DELETED)
return CHANNEL_DELETED;
- // SendIOBuffer() checks |state_|, so it is best not to change it until after
- // SendIOBuffer() returns.
- state_ = (state_ == CONNECTED) ? SEND_CLOSED : CLOSE_WAIT;
return CHANNEL_ALIVE;
}
@@ -958,7 +963,10 @@
if (CHANNEL_DELETED ==
notification_sender_->SendImmediately(event_interface_.get()))
return CHANNEL_DELETED;
- return event_interface_->OnDropChannel(was_clean, code, reason);
+ ChannelState result =
+ event_interface_->OnDropChannel(was_clean, code, reason);
+ DCHECK_EQ(CHANNEL_DELETED, result);
+ return result;
}
void WebSocketChannel::CloseTimeout() {