Chromium Code Reviews| Index: net/socket/socket_posix.cc |
| diff --git a/net/socket/socket_posix.cc b/net/socket/socket_posix.cc |
| index 20cc92bf593a6d14ccf9cf6e94f5a0ae5f7411fe..b98be1c13fc13568bd11ef5742f3ea3dbcb1620c 100644 |
| --- a/net/socket/socket_posix.cc |
| +++ b/net/socket/socket_posix.cc |
| @@ -253,10 +253,26 @@ bool SocketPosix::IsConnectedAndIdle() const { |
| int SocketPosix::Read(IOBuffer* buf, |
| int buf_len, |
| const CompletionCallback& callback) { |
| + // Use base::Unretained() is safe here because OnFileCanReadWithoutBlocking() |
| + // won't be called if |this| is gone. |
| + int rv = |
| + ReadIfReady(buf, buf_len, |
| + base::Bind(&SocketPosix::RetryRead, base::Unretained(this))); |
| + 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 |
|
Bence
2017/03/03 16:33:41
What does this comment mean? Could it be removed?
xunjieli
2017/03/03 19:41:05
Done. Removed. I think having a callback as a requ
|
| DCHECK(!callback.is_null()); |
| DCHECK_LT(0, buf_len); |
| @@ -272,9 +288,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; |
| } |
| @@ -375,10 +389,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() |
|
Bence
2017/03/03 16:33:41
Optional: remove this comment, remove DCHECK from
xunjieli
2017/03/03 19:41:05
Done.
|
| ReadCompleted(); |
| } |
| } |
| @@ -453,16 +467,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, base::Unretained(this))); |
| + 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) { |