Index: net/socket/socket_posix.cc |
diff --git a/net/socket/socket_posix.cc b/net/socket/socket_posix.cc |
index 09d9baec87e0139e41226b8a1b8b5a8de5c6a6c6..8f71e74923413a26b1054af4431eea47ae6932b9 100644 |
--- a/net/socket/socket_posix.cc |
+++ b/net/socket/socket_posix.cc |
@@ -62,7 +62,8 @@ SocketPosix::SocketPosix() |
: socket_fd_(kInvalidSocket), |
read_buf_len_(0), |
write_buf_len_(0), |
- waiting_connect_(false) {} |
+ waiting_connect_(false), |
+ weak_factory_(this) {} |
SocketPosix::~SocketPosix() { |
Close(); |
@@ -250,10 +251,23 @@ bool SocketPosix::IsConnectedAndIdle() const { |
int SocketPosix::Read(IOBuffer* buf, |
int buf_len, |
const CompletionCallback& callback) { |
+ int rv = ReadIfReady(buf, buf_len, base::Bind(&SocketPosix::RetryRead, |
+ weak_factory_.GetWeakPtr())); |
davidben
2017/02/10 23:33:48
Do you need a WeakPtr here? Since the callback won
xunjieli
2017/02/13 20:28:18
Done. You are right. I confused this one with the
|
+ if (rv == ERR_IO_PENDING) { |
+ read_buf_ = buf; |
+ read_buf_len_ = buf_len; |
+ read_callback_ = callback; |
+ } |
+ return rv; |
+} |
+ |
+int SocketPosix::ReadIfReady(IOBuffer* buf, |
+ int buf_len, |
+ const CompletionCallback& callback) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
DCHECK_NE(kInvalidSocket, socket_fd_); |
DCHECK(!waiting_connect_); |
- CHECK(read_callback_.is_null()); |
+ CHECK(read_if_ready_callback_.is_null()); |
// Synchronous operation not supported |
DCHECK(!callback.is_null()); |
DCHECK_LT(0, buf_len); |
@@ -269,9 +283,7 @@ int SocketPosix::Read(IOBuffer* buf, |
return MapSystemError(errno); |
} |
- read_buf_ = buf; |
- read_buf_len_ = buf_len; |
- read_callback_ = callback; |
+ read_if_ready_callback_ = callback; |
return ERR_IO_PENDING; |
} |
@@ -372,10 +384,10 @@ void SocketPosix::DetachFromThread() { |
void SocketPosix::OnFileCanReadWithoutBlocking(int fd) { |
TRACE_EVENT0(kNetTracingCategory, |
"SocketPosix::OnFileCanReadWithoutBlocking"); |
- DCHECK(!accept_callback_.is_null() || !read_callback_.is_null()); |
+ DCHECK(!accept_callback_.is_null() || !read_if_ready_callback_.is_null()); |
if (!accept_callback_.is_null()) { |
AcceptCompleted(); |
- } else { // !read_callback_.is_null() |
+ } else { // !read_if_ready_callback_.is_null() |
ReadCompleted(); |
} |
} |
@@ -450,16 +462,29 @@ int SocketPosix::DoRead(IOBuffer* buf, int buf_len) { |
return rv >= 0 ? rv : MapSystemError(errno); |
} |
+void SocketPosix::RetryRead(int rv) { |
+ DCHECK(read_callback_); |
+ DCHECK(read_buf_); |
+ DCHECK_LT(0, read_buf_len_); |
+ |
+ if (rv == OK) { |
+ rv = ReadIfReady( |
+ read_buf_.get(), read_buf_len_, |
+ base::Bind(&SocketPosix::RetryRead, weak_factory_.GetWeakPtr())); |
+ if (rv == ERR_IO_PENDING) |
+ return; |
+ } |
+ read_buf_ = nullptr; |
+ read_buf_len_ = 0; |
+ base::ResetAndReturn(&read_callback_).Run(rv); |
+} |
+ |
void SocketPosix::ReadCompleted() { |
- int rv = DoRead(read_buf_.get(), read_buf_len_); |
- if (rv == ERR_IO_PENDING) |
- return; |
+ DCHECK(read_if_ready_callback_); |
bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); |
DCHECK(ok); |
- read_buf_ = NULL; |
- read_buf_len_ = 0; |
- base::ResetAndReturn(&read_callback_).Run(rv); |
+ base::ResetAndReturn(&read_if_ready_callback_).Run(OK); |
} |
int SocketPosix::DoWrite(IOBuffer* buf, int buf_len) { |