diff options
author | tyoshino@chromium.org <tyoshino@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-19 16:48:22 +0000 |
---|---|---|
committer | tyoshino@chromium.org <tyoshino@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-19 16:48:22 +0000 |
commit | 3d563769f1f14cfd51a0320eb45ee92dc52c5aa1 (patch) | |
tree | 161fa00935ce5dfef14f622f13ff44a3d68fe084 /net/websockets | |
parent | f9b7eeab4dd12df02205de7a76daf295ff3d125b (diff) | |
download | chromium_src-3d563769f1f14cfd51a0320eb45ee92dc52c5aa1.zip chromium_src-3d563769f1f14cfd51a0320eb45ee92dc52c5aa1.tar.gz chromium_src-3d563769f1f14cfd51a0320eb45ee92dc52c5aa1.tar.bz2 |
[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
Diffstat (limited to 'net/websockets')
-rw-r--r-- | net/websockets/websocket_channel.cc | 34 | ||||
-rw-r--r-- | net/websockets/websocket_channel.h | 2 |
2 files changed, 23 insertions, 13 deletions
diff --git a/net/websockets/websocket_channel.cc b/net/websockets/websocket_channel.cc index e8122b6..ed8a92b 100644 --- a/net/websockets/websocket_channel.cc +++ b/net/websockets/websocket_channel.cc @@ -395,13 +395,16 @@ void WebSocketChannel::StartClosingHandshake(uint16 code, // 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 @@ ChannelState WebSocketChannel::WriteFrames() { 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 @@ ChannelState WebSocketChannel::HandleFrameByState( 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 @@ ChannelState WebSocketChannel::SendIOBuffer( 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 @@ ChannelState WebSocketChannel::SendIOBuffer( 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 @@ ChannelState WebSocketChannel::FailChannel(const std::string& message, 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 @@ ChannelState WebSocketChannel::SendClose(uint16 code, 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 @@ ChannelState WebSocketChannel::DoDropChannel(bool was_clean, 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() { diff --git a/net/websockets/websocket_channel.h b/net/websockets/websocket_channel.h index fa7a133..183f2be 100644 --- a/net/websockets/websocket_channel.h +++ b/net/websockets/websocket_channel.h @@ -263,6 +263,8 @@ class NET_EXPORT WebSocketChannel { // Drop this channel. // If there are pending opening handshake notifications, notify them // before dropping. + // + // Always returns CHANNEL_DELETED. ChannelState DoDropChannel(bool was_clean, uint16 code, const std::string& reason); |