| Index: net/socket/tcp_client_socket_libevent.cc
|
| diff --git a/net/socket/tcp_client_socket_libevent.cc b/net/socket/tcp_client_socket_libevent.cc
|
| index 2d110d09a2d07123ac76051a14545388678cb0f9..bff188f3ec8b8167a11eadb55940a809c3fd4a17 100644
|
| --- a/net/socket/tcp_client_socket_libevent.cc
|
| +++ b/net/socket/tcp_client_socket_libevent.cc
|
| @@ -130,7 +130,7 @@ TCPClientSocketLibevent::TCPClientSocketLibevent(
|
| current_ai_(NULL),
|
| read_watcher_(this),
|
| write_watcher_(this),
|
| - read_callback_(NULL),
|
| + old_read_callback_(NULL),
|
| old_write_callback_(NULL),
|
| next_connect_state_(CONNECT_STATE_NONE),
|
| connect_os_error_(0),
|
| @@ -465,7 +465,7 @@ int TCPClientSocketLibevent::Read(IOBuffer* buf,
|
| DCHECK(CalledOnValidThread());
|
| DCHECK_NE(kInvalidSocket, socket_);
|
| DCHECK(!waiting_connect());
|
| - DCHECK(!read_callback_);
|
| + DCHECK(!old_read_callback_ && read_callback_.is_null());
|
| // Synchronous operation not supported
|
| DCHECK(callback);
|
| DCHECK_GT(buf_len, 0);
|
| @@ -495,6 +495,45 @@ int TCPClientSocketLibevent::Read(IOBuffer* buf,
|
|
|
| read_buf_ = buf;
|
| read_buf_len_ = buf_len;
|
| + old_read_callback_ = callback;
|
| + return ERR_IO_PENDING;
|
| +}
|
| +int TCPClientSocketLibevent::Read(IOBuffer* buf,
|
| + int buf_len,
|
| + const CompletionCallback& callback) {
|
| + DCHECK(CalledOnValidThread());
|
| + DCHECK_NE(kInvalidSocket, socket_);
|
| + DCHECK(!waiting_connect());
|
| + DCHECK(!old_read_callback_ && read_callback_.is_null());
|
| + // Synchronous operation not supported
|
| + DCHECK(!callback.is_null());
|
| + DCHECK_GT(buf_len, 0);
|
| +
|
| + int nread = HANDLE_EINTR(read(socket_, buf->data(), buf_len));
|
| + if (nread >= 0) {
|
| + base::StatsCounter read_bytes("tcp.read_bytes");
|
| + read_bytes.Add(nread);
|
| + num_bytes_read_ += static_cast<int64>(nread);
|
| + if (nread > 0)
|
| + use_history_.set_was_used_to_convey_data();
|
| + net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, nread,
|
| + buf->data());
|
| + return nread;
|
| + }
|
| + if (errno != EAGAIN && errno != EWOULDBLOCK) {
|
| + DVLOG(1) << "read failed, errno " << errno;
|
| + return MapSystemError(errno);
|
| + }
|
| +
|
| + if (!MessageLoopForIO::current()->WatchFileDescriptor(
|
| + socket_, true, MessageLoopForIO::WATCH_READ,
|
| + &read_socket_watcher_, &read_watcher_)) {
|
| + DVLOG(1) << "WatchFileDescriptor failed on read, errno " << errno;
|
| + return MapSystemError(errno);
|
| + }
|
| +
|
| + read_buf_ = buf;
|
| + read_buf_len_ = buf_len;
|
| read_callback_ = callback;
|
| return ERR_IO_PENDING;
|
| }
|
| @@ -618,12 +657,18 @@ void TCPClientSocketLibevent::LogConnectCompletion(int net_error) {
|
|
|
| void TCPClientSocketLibevent::DoReadCallback(int rv) {
|
| DCHECK_NE(rv, ERR_IO_PENDING);
|
| - DCHECK(read_callback_);
|
| + DCHECK(old_read_callback_ || !read_callback_.is_null());
|
|
|
| // since Run may result in Read being called, clear read_callback_ up front.
|
| - OldCompletionCallback* c = read_callback_;
|
| - read_callback_ = NULL;
|
| - c->Run(rv);
|
| + if (old_read_callback_) {
|
| + OldCompletionCallback* c = old_read_callback_;
|
| + old_read_callback_ = NULL;
|
| + c->Run(rv);
|
| + } else {
|
| + CompletionCallback c = read_callback_;
|
| + read_callback_.Reset();
|
| + c.Run(rv);
|
| + }
|
| }
|
|
|
| void TCPClientSocketLibevent::DoWriteCallback(int rv) {
|
|
|