Index: net/socket/socks5_client_socket.cc |
diff --git a/net/socket/socks5_client_socket.cc b/net/socket/socks5_client_socket.cc |
index 004b67c669fe0c949500c4eb8eb1a50ea47ef126..777ce0c26a16329e2a2c8cd9ad2e88a932516579 100644 |
--- a/net/socket/socks5_client_socket.cc |
+++ b/net/socket/socks5_client_socket.cc |
@@ -5,6 +5,7 @@ |
#include "net/socket/socks5_client_socket.h" |
#include "base/basictypes.h" |
+#include "base/callback_helpers.h" |
#include "base/compiler_specific.h" |
#include "base/debug/trace_event.h" |
#include "base/format_macros.h" |
@@ -38,6 +39,7 @@ SOCKS5ClientSocket::SOCKS5ClientSocket( |
bytes_sent_(0), |
bytes_received_(0), |
read_header_size(kReadHeaderSize), |
+ was_ever_used_(false), |
host_request_info_(req_info), |
net_log_(transport_->socket()->NetLog()) { |
} |
@@ -109,11 +111,7 @@ void SOCKS5ClientSocket::SetOmniboxSpeculation() { |
} |
bool SOCKS5ClientSocket::WasEverUsed() const { |
- if (transport_.get() && transport_->socket()) { |
- return transport_->socket()->WasEverUsed(); |
- } |
- NOTREACHED(); |
- return false; |
+ return was_ever_used_; |
} |
bool SOCKS5ClientSocket::UsingTCPFastOpen() const { |
@@ -156,19 +154,33 @@ int SOCKS5ClientSocket::Read(IOBuffer* buf, int buf_len, |
DCHECK(completed_handshake_); |
DCHECK_EQ(STATE_NONE, next_state_); |
DCHECK(user_callback_.is_null()); |
- |
- return transport_->socket()->Read(buf, buf_len, callback); |
+ DCHECK(!callback.is_null()); |
+ |
+ int rv = transport_->socket()->Read( |
+ buf, buf_len, |
+ base::Bind(&SOCKS5ClientSocket::OnReadWriteComplete, |
+ base::Unretained(this), callback)); |
+ if (rv > 0) |
+ was_ever_used_ = true; |
+ return rv; |
} |
// Write is called by the transport layer. This can only be done if the |
// SOCKS handshake is complete. |
int SOCKS5ClientSocket::Write(IOBuffer* buf, int buf_len, |
- const CompletionCallback& callback) { |
+ const CompletionCallback& callback) { |
DCHECK(completed_handshake_); |
DCHECK_EQ(STATE_NONE, next_state_); |
DCHECK(user_callback_.is_null()); |
- |
- return transport_->socket()->Write(buf, buf_len, callback); |
+ DCHECK(!callback.is_null()); |
+ |
+ int rv = transport_->socket()->Write( |
+ buf, buf_len, |
+ base::Bind(&SOCKS5ClientSocket::OnReadWriteComplete, |
+ base::Unretained(this), callback)); |
+ if (rv > 0) |
+ was_ever_used_ = true; |
+ return rv; |
} |
bool SOCKS5ClientSocket::SetReceiveBufferSize(int32 size) { |
@@ -185,9 +197,7 @@ void SOCKS5ClientSocket::DoCallback(int result) { |
// Since Run() may result in Read being called, |
// clear user_callback_ up front. |
- CompletionCallback c = user_callback_; |
- user_callback_.Reset(); |
- c.Run(result); |
+ base::ResetAndReturn(&user_callback_).Run(result); |
} |
void SOCKS5ClientSocket::OnIOComplete(int result) { |
@@ -199,6 +209,16 @@ void SOCKS5ClientSocket::OnIOComplete(int result) { |
} |
} |
+void SOCKS5ClientSocket::OnReadWriteComplete(const CompletionCallback& callback, |
+ int result) { |
+ DCHECK_NE(ERR_IO_PENDING, result); |
+ DCHECK(!callback.is_null()); |
+ |
+ if (result > 0) |
+ was_ever_used_ = true; |
+ callback.Run(result); |
+} |
+ |
int SOCKS5ClientSocket::DoLoop(int last_io_result) { |
DCHECK_NE(next_state_, STATE_NONE); |
int rv = last_io_result; |