Chromium Code Reviews| Index: extensions/browser/api/cast_channel/cast_socket.cc |
| diff --git a/extensions/browser/api/cast_channel/cast_socket.cc b/extensions/browser/api/cast_channel/cast_socket.cc |
| index f446bff88d53957c8a4bad5af185a03b251dea62..38a6477b5d10507b67da56b0297a8a5b7cacf093 100644 |
| --- a/extensions/browser/api/cast_channel/cast_socket.cc |
| +++ b/extensions/browser/api/cast_channel/cast_socket.cc |
| @@ -99,7 +99,9 @@ CastSocket::CastSocket(const std::string& owner_extension_id, |
| current_read_buffer_ = header_read_buffer_; |
| } |
| -CastSocket::~CastSocket() { } |
| +CastSocket::~CastSocket() { |
| + CloseInternal(); |
| +} |
| ReadyState CastSocket::ready_state() const { |
| return ready_state_; |
| @@ -176,19 +178,21 @@ void CastSocket::Connect(const net::CompletionCallback& callback) { |
| connect_callback_ = callback; |
| connect_state_ = CONN_STATE_TCP_CONNECT; |
| if (connect_timeout_.InMicroseconds() > 0) { |
| - GetTimer()->Start( |
| - FROM_HERE, |
| - connect_timeout_, |
| - base::Bind(&CastSocket::CancelConnect, AsWeakPtr())); |
| + DCHECK(cancel_connect_callback_.is_null()); |
| + cancel_connect_callback_ = base::Bind(&CastSocket::CancelConnect, |
| + base::Unretained(this)); |
| + GetTimer()->Start(FROM_HERE, connect_timeout_, cancel_connect_callback_); |
| } |
| DoConnectLoop(net::OK); |
| } |
| void CastSocket::PostTaskToStartConnectLoop(int result) { |
| DCHECK(CalledOnValidThread()); |
| - base::MessageLoop::current()->PostTask( |
| - FROM_HERE, |
| - base::Bind(&CastSocket::DoConnectLoop, AsWeakPtr(), result)); |
| + DCHECK(connect_loop_callback_.is_null()); |
| + connect_loop_callback_ = base::Bind(&CastSocket::DoConnectLoop, |
| + base::Unretained(this), |
| + result); |
| + base::MessageLoop::current()->PostTask(FROM_HERE, connect_loop_callback_); |
|
Kevin M
2014/07/28 22:08:16
Should this be turned into PostNonNestableTask now
Wez
2014/07/28 23:14:56
PostNonNestableTask() isn't required here, since w
Wez
2014/07/28 23:14:56
This will blow up if PostTaskToStartConnectLoop()
mark a. foltz
2014/07/29 00:16:24
So Reset()-ing the callback in the dtor is a no-op
mark a. foltz
2014/07/29 00:16:25
Acknowledged.
Wez
2014/07/29 00:41:25
base::Closure is ref-counted, so when you message_
|
| } |
| void CastSocket::CancelConnect() { |
| @@ -261,8 +265,9 @@ int CastSocket::DoTcpConnect() { |
| VLOG_WITH_CONNECTION(1) << "DoTcpConnect"; |
| connect_state_ = CONN_STATE_TCP_CONNECT_COMPLETE; |
| tcp_socket_ = CreateTcpSocket(); |
| + DCHECK(connect_loop_callback_.is_null()); |
| return tcp_socket_->Connect( |
| - base::Bind(&CastSocket::DoConnectLoop, AsWeakPtr())); |
| + base::Bind(&CastSocket::DoConnectLoop, base::Unretained(this))); |
| } |
| int CastSocket::DoTcpConnectComplete(int result) { |
| @@ -280,8 +285,9 @@ int CastSocket::DoSslConnect() { |
| VLOG_WITH_CONNECTION(1) << "DoSslConnect"; |
| connect_state_ = CONN_STATE_SSL_CONNECT_COMPLETE; |
| socket_ = CreateSslSocket(tcp_socket_.PassAs<net::StreamSocket>()); |
| + DCHECK(connect_loop_callback_.is_null()); |
| return socket_->Connect( |
| - base::Bind(&CastSocket::DoConnectLoop, AsWeakPtr())); |
| + base::Bind(&CastSocket::DoConnectLoop, base::Unretained(this))); |
| } |
| int CastSocket::DoSslConnectComplete(int result) { |
| @@ -305,13 +311,17 @@ int CastSocket::DoAuthChallengeSend() { |
| << CastMessageToString(challenge_message); |
| // Post a task to send auth challenge so that DoWriteLoop is not nested inside |
| // DoConnectLoop. This is not strictly necessary but keeps the write loop |
| - // code decoupled from connect loop code. |
| - base::MessageLoop::current()->PostTask( |
| - FROM_HERE, |
| - base::Bind(&CastSocket::SendCastMessageInternal, |
| - AsWeakPtr(), |
| - challenge_message, |
| - base::Bind(&CastSocket::DoConnectLoop, AsWeakPtr()))); |
| + // code decoupleld from connect loop code. |
|
Kevin M
2014/07/28 22:08:16
typo
mark a. foltz
2014/07/29 00:16:24
Done.
|
| + DCHECK(connect_loop_callback_.is_null()); |
| + DCHECK(send_auth_challenge_callback_.is_null()); |
| + send_auth_challenge_callback_ = |
| + base::Bind(&CastSocket::SendCastMessageInternal, |
|
Kevin M
2014/07/28 22:08:16
4 space indentation
mark a. foltz
2014/07/29 00:16:25
Done.
|
| + base::Unretained(this), |
| + challenge_message, |
| + base::Bind(&CastSocket::DoConnectLoop, |
| + base::Unretained(this))); |
| + base::MessageLoop::current()->PostTask(FROM_HERE, |
| + send_auth_challenge_callback_); |
|
Wez
2014/07/28 23:14:56
This will blow up, as above.
mark a. foltz
2014/07/29 00:16:25
Acknowledged.
|
| // Always return IO_PENDING since the result is always asynchronous. |
| return net::ERR_IO_PENDING; |
| } |
| @@ -354,15 +364,32 @@ void CastSocket::DoConnectCallback(int result) { |
| } |
| void CastSocket::Close(const net::CompletionCallback& callback) { |
| + CloseInternal(); |
| + callback.Run(net::OK); |
| + // |callback| can delete |this| |
| +} |
| + |
| +void CastSocket::CloseInternal() { |
| DCHECK(CalledOnValidThread()); |
| + if (ready_state_ == READY_STATE_CLOSED) { |
| + return; |
| + } |
| VLOG_WITH_CONNECTION(1) << "Close ReadyState = " << ready_state_; |
| tcp_socket_.reset(); |
| socket_.reset(); |
| cert_verifier_.reset(); |
| transport_security_state_.reset(); |
| + // Reset callbacks passed into us. Or should we invoke them with an error? |
|
Kevin M
2014/07/28 22:08:16
Stop the timer?
mark a. foltz
2014/07/29 00:16:24
Done.
|
| + connect_callback_.Reset(); |
|
Kevin M
2014/07/28 22:08:16
Question: does resetting the callbacks also dequeu
mark a. foltz
2014/07/29 00:16:24
Good question.
|
| + for (; !write_queue_.empty(); write_queue_.pop()) { |
| + write_queue_.front().callback.Reset(); |
| + } |
| + // Reset callbacks that we queued ourselves. |
| + connect_loop_callback_.Reset(); |
| + read_loop_callback_.Reset(); |
| + cancel_connect_callback_.Reset(); |
| + send_auth_challenge_callback_.Reset(); |
| ready_state_ = READY_STATE_CLOSED; |
| - callback.Run(net::OK); |
| - // |callback| can delete |this| |
| } |
| void CastSocket::SendMessage(const MessageInfo& message, |
| @@ -454,11 +481,10 @@ int CastSocket::DoWrite() { |
| << request.io_buffer->BytesConsumed(); |
| write_state_ = WRITE_STATE_WRITE_COMPLETE; |
| - |
| return socket_->Write( |
| request.io_buffer.get(), |
| request.io_buffer->BytesRemaining(), |
| - base::Bind(&CastSocket::DoWriteLoop, AsWeakPtr())); |
| + base::Bind(&CastSocket::DoWriteLoop, base::Unretained(this))); |
| } |
| int CastSocket::DoWriteComplete(int result) { |
| @@ -526,9 +552,10 @@ int CastSocket::DoWriteError(int result) { |
| void CastSocket::PostTaskToStartReadLoop() { |
| DCHECK(CalledOnValidThread()); |
| - base::MessageLoop::current()->PostTask( |
| - FROM_HERE, |
| - base::Bind(&CastSocket::StartReadLoop, AsWeakPtr())); |
| + DCHECK(read_loop_callback_.is_null()); |
| + read_loop_callback_ = base::Bind(&CastSocket::StartReadLoop, |
| + base::Unretained(this)); |
| + base::MessageLoop::current()->PostTask(FROM_HERE, read_loop_callback_); |
|
Wez
2014/07/28 23:14:56
Boom!
mark a. foltz
2014/07/29 00:16:25
Acknowledged.
|
| } |
| void CastSocket::StartReadLoop() { |
| @@ -603,7 +630,7 @@ int CastSocket::DoRead() { |
| return socket_->Read( |
| current_read_buffer_.get(), |
| num_bytes_to_read, |
| - base::Bind(&CastSocket::DoReadLoop, AsWeakPtr())); |
| + base::Bind(&CastSocket::DoReadLoop, base::Unretained(this))); |
| } |
| int CastSocket::DoReadComplete(int result) { |
| @@ -723,8 +750,7 @@ bool CastSocket::Serialize(const CastMessage& message_proto, |
| void CastSocket::CloseWithError(ChannelError error) { |
| DCHECK(CalledOnValidThread()); |
| - socket_.reset(NULL); |
| - ready_state_ = READY_STATE_CLOSED; |
| + CloseInternal(); |
| error_state_ = error; |
| if (delegate_) |
| delegate_->OnError(this, error); |
| @@ -756,7 +782,7 @@ void CastSocket::MessageHeader::SetMessageSize(size_t size) { |
| void CastSocket::MessageHeader::PrependToString(std::string* str) { |
| MessageHeader output = *this; |
| output.message_size = base::HostToNet32(message_size); |
| - size_t header_size = base::checked_cast<size_t,uint32>( |
| + size_t header_size = base::checked_cast<size_t, uint32>( |
| MessageHeader::header_size()); |
| scoped_ptr<char, base::FreeDeleter> char_array( |
| static_cast<char*>(malloc(header_size))); |
| @@ -769,7 +795,7 @@ void CastSocket::MessageHeader::PrependToString(std::string* str) { |
| void CastSocket::MessageHeader::ReadFromIOBuffer( |
| net::GrowableIOBuffer* buffer, MessageHeader* header) { |
| uint32 message_size; |
| - size_t header_size = base::checked_cast<size_t,uint32>( |
| + size_t header_size = base::checked_cast<size_t, uint32>( |
| MessageHeader::header_size()); |
| memcpy(&message_size, buffer->StartOfBuffer(), header_size); |
| header->message_size = base::NetToHost32(message_size); |