Chromium Code Reviews| 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) { |