From 250fc658c56cb3c6944bd0fd1b88973f2e6d1ced Mon Sep 17 00:00:00 2001 From: jbauch Date: Sun, 28 Feb 2016 15:06:40 -0800 Subject: [PATCH] Lazily allocate output buffer for AsyncTCPSocket. As a follow-up to https://codereview.webrtc.org/1737053006/ this CL further improves memory usage by lazily allocating output buffers up to the passed maximum size. This also changes the output buffer to a Buffer object. BUG= Review URL: https://codereview.webrtc.org/1741413002 Cr-Commit-Position: refs/heads/master@{#11801} --- webrtc/base/asynctcpsocket.cc | 36 ++++++++++++++++------------------- webrtc/base/asynctcpsocket.h | 10 ++++++---- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/webrtc/base/asynctcpsocket.cc b/webrtc/base/asynctcpsocket.cc index 7ec6dc8bc2..31dec92367 100644 --- a/webrtc/base/asynctcpsocket.cc +++ b/webrtc/base/asynctcpsocket.cc @@ -55,12 +55,10 @@ AsyncTCPSocketBase::AsyncTCPSocketBase(AsyncSocket* socket, bool listen, listen_(listen), insize_(max_packet_size), inpos_(0), - outsize_(max_packet_size), - outpos_(0) { + max_outsize_(max_packet_size) { if (!listen_) { // Listening sockets don't send/receive data, so they don't need buffers. inbuf_.reset(new char[insize_]); - outbuf_.reset(new char[outsize_]); } RTC_DCHECK(socket_.get() != NULL); @@ -138,41 +136,39 @@ int AsyncTCPSocketBase::SendTo(const void *pv, size_t cb, } int AsyncTCPSocketBase::SendRaw(const void * pv, size_t cb) { - if (outpos_ + cb > outsize_) { + if (outbuf_.size() + cb > max_outsize_) { socket_->SetError(EMSGSIZE); return -1; } - RTC_DCHECK(outbuf_.get()); - memcpy(outbuf_.get() + outpos_, pv, cb); - outpos_ += cb; + RTC_DCHECK(!listen_); + outbuf_.AppendData(static_cast(pv), cb); return FlushOutBuffer(); } int AsyncTCPSocketBase::FlushOutBuffer() { - RTC_DCHECK(outbuf_.get()); - int res = socket_->Send(outbuf_.get(), outpos_); + RTC_DCHECK(!listen_); + int res = socket_->Send(outbuf_.data(), outbuf_.size()); if (res <= 0) { return res; } - if (static_cast(res) <= outpos_) { - outpos_ -= res; - } else { + if (static_cast(res) > outbuf_.size()) { RTC_NOTREACHED(); return -1; } - if (outpos_ > 0) { - memmove(outbuf_.get(), outbuf_.get() + res, outpos_); + size_t new_size = outbuf_.size() - res; + if (new_size > 0) { + memmove(outbuf_.data(), outbuf_.data() + res, new_size); } + outbuf_.SetSize(new_size); return res; } void AsyncTCPSocketBase::AppendToOutBuffer(const void* pv, size_t cb) { - RTC_DCHECK(outpos_ + cb < outsize_); - RTC_DCHECK(outbuf_.get()); - memcpy(outbuf_.get() + outpos_, pv, cb); - outpos_ += cb; + RTC_DCHECK(outbuf_.size() + cb <= max_outsize_); + RTC_DCHECK(!listen_); + outbuf_.AppendData(static_cast(pv), cb); } void AsyncTCPSocketBase::OnConnectEvent(AsyncSocket* socket) { @@ -222,11 +218,11 @@ void AsyncTCPSocketBase::OnReadEvent(AsyncSocket* socket) { void AsyncTCPSocketBase::OnWriteEvent(AsyncSocket* socket) { RTC_DCHECK(socket_.get() == socket); - if (outpos_ > 0) { + if (outbuf_.size() > 0) { FlushOutBuffer(); } - if (outpos_ == 0) { + if (outbuf_.size() == 0) { SignalReadyToSend(this); } } diff --git a/webrtc/base/asynctcpsocket.h b/webrtc/base/asynctcpsocket.h index b0d0399e34..9ee37b2728 100644 --- a/webrtc/base/asynctcpsocket.h +++ b/webrtc/base/asynctcpsocket.h @@ -12,6 +12,7 @@ #define WEBRTC_BASE_ASYNCTCPSOCKET_H_ #include "webrtc/base/asyncpacketsocket.h" +#include "webrtc/base/buffer.h" #include "webrtc/base/scoped_ptr.h" #include "webrtc/base/socketfactory.h" @@ -59,8 +60,8 @@ class AsyncTCPSocketBase : public AsyncPacketSocket { void AppendToOutBuffer(const void* pv, size_t cb); // Helper methods for |outpos_|. - bool IsOutBufferEmpty() const { return outpos_ == 0; } - void ClearOutBuffer() { outpos_ = 0; } + bool IsOutBufferEmpty() const { return outbuf_.size() == 0; } + void ClearOutBuffer() { outbuf_.Clear(); } private: // Called by the underlying socket @@ -72,8 +73,9 @@ class AsyncTCPSocketBase : public AsyncPacketSocket { scoped_ptr socket_; bool listen_; scoped_ptr inbuf_; - scoped_ptr outbuf_; - size_t insize_, inpos_, outsize_, outpos_; + Buffer outbuf_; + size_t insize_, inpos_; + size_t max_outsize_; RTC_DISALLOW_COPY_AND_ASSIGN(AsyncTCPSocketBase); };