Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(827)

Side by Side Diff: webrtc/base/asynctcpsocket.cc

Issue 1737053006: Don't allocate buffers for listening sockets. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/base/asynctcpsocket.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/base/asynctcpsocket.h" 11 #include "webrtc/base/asynctcpsocket.h"
12 12
13 #include <string.h> 13 #include <string.h>
14 14
15 #include "webrtc/base/byteorder.h" 15 #include "webrtc/base/byteorder.h"
16 #include "webrtc/base/checks.h"
16 #include "webrtc/base/common.h" 17 #include "webrtc/base/common.h"
17 #include "webrtc/base/logging.h" 18 #include "webrtc/base/logging.h"
18 19
19 #if defined(WEBRTC_POSIX) 20 #if defined(WEBRTC_POSIX)
20 #include <errno.h> 21 #include <errno.h>
21 #endif // WEBRTC_POSIX 22 #endif // WEBRTC_POSIX
22 23
23 namespace rtc { 24 namespace rtc {
24 25
25 static const size_t kMaxPacketSize = 64 * 1024; 26 static const size_t kMaxPacketSize = 64 * 1024;
(...skipping 23 matching lines...) Expand all
49 } 50 }
50 51
51 AsyncTCPSocketBase::AsyncTCPSocketBase(AsyncSocket* socket, bool listen, 52 AsyncTCPSocketBase::AsyncTCPSocketBase(AsyncSocket* socket, bool listen,
52 size_t max_packet_size) 53 size_t max_packet_size)
53 : socket_(socket), 54 : socket_(socket),
54 listen_(listen), 55 listen_(listen),
55 insize_(max_packet_size), 56 insize_(max_packet_size),
56 inpos_(0), 57 inpos_(0),
57 outsize_(max_packet_size), 58 outsize_(max_packet_size),
58 outpos_(0) { 59 outpos_(0) {
59 inbuf_ = new char[insize_]; 60 if (!listen_) {
60 outbuf_ = new char[outsize_]; 61 // Listening sockets don't send/receive data, so they don't need buffers.
62 inbuf_.reset(new char[insize_]);
63 outbuf_.reset(new char[outsize_]);
64 }
61 65
62 ASSERT(socket_.get() != NULL); 66 RTC_DCHECK(socket_.get() != NULL);
63 socket_->SignalConnectEvent.connect( 67 socket_->SignalConnectEvent.connect(
64 this, &AsyncTCPSocketBase::OnConnectEvent); 68 this, &AsyncTCPSocketBase::OnConnectEvent);
65 socket_->SignalReadEvent.connect(this, &AsyncTCPSocketBase::OnReadEvent); 69 socket_->SignalReadEvent.connect(this, &AsyncTCPSocketBase::OnReadEvent);
66 socket_->SignalWriteEvent.connect(this, &AsyncTCPSocketBase::OnWriteEvent); 70 socket_->SignalWriteEvent.connect(this, &AsyncTCPSocketBase::OnWriteEvent);
67 socket_->SignalCloseEvent.connect(this, &AsyncTCPSocketBase::OnCloseEvent); 71 socket_->SignalCloseEvent.connect(this, &AsyncTCPSocketBase::OnCloseEvent);
68 72
69 if (listen_) { 73 if (listen_) {
70 if (socket_->Listen(kListenBacklog) < 0) { 74 if (socket_->Listen(kListenBacklog) < 0) {
71 LOG(LS_ERROR) << "Listen() failed with error " << socket_->GetError(); 75 LOG(LS_ERROR) << "Listen() failed with error " << socket_->GetError();
72 } 76 }
73 } 77 }
74 } 78 }
75 79
76 AsyncTCPSocketBase::~AsyncTCPSocketBase() { 80 AsyncTCPSocketBase::~AsyncTCPSocketBase() {}
77 delete [] inbuf_;
78 delete [] outbuf_;
79 }
80 81
81 SocketAddress AsyncTCPSocketBase::GetLocalAddress() const { 82 SocketAddress AsyncTCPSocketBase::GetLocalAddress() const {
82 return socket_->GetLocalAddress(); 83 return socket_->GetLocalAddress();
83 } 84 }
84 85
85 SocketAddress AsyncTCPSocketBase::GetRemoteAddress() const { 86 SocketAddress AsyncTCPSocketBase::GetRemoteAddress() const {
86 return socket_->GetRemoteAddress(); 87 return socket_->GetRemoteAddress();
87 } 88 }
88 89
89 int AsyncTCPSocketBase::Close() { 90 int AsyncTCPSocketBase::Close() {
90 return socket_->Close(); 91 return socket_->Close();
91 } 92 }
92 93
93 AsyncTCPSocket::State AsyncTCPSocketBase::GetState() const { 94 AsyncTCPSocket::State AsyncTCPSocketBase::GetState() const {
94 switch (socket_->GetState()) { 95 switch (socket_->GetState()) {
95 case Socket::CS_CLOSED: 96 case Socket::CS_CLOSED:
96 return STATE_CLOSED; 97 return STATE_CLOSED;
97 case Socket::CS_CONNECTING: 98 case Socket::CS_CONNECTING:
98 if (listen_) { 99 if (listen_) {
99 return STATE_BOUND; 100 return STATE_BOUND;
100 } else { 101 } else {
101 return STATE_CONNECTING; 102 return STATE_CONNECTING;
102 } 103 }
103 case Socket::CS_CONNECTED: 104 case Socket::CS_CONNECTED:
104 return STATE_CONNECTED; 105 return STATE_CONNECTED;
105 default: 106 default:
106 ASSERT(false); 107 RTC_NOTREACHED();
107 return STATE_CLOSED; 108 return STATE_CLOSED;
108 } 109 }
109 } 110 }
110 111
111 int AsyncTCPSocketBase::GetOption(Socket::Option opt, int* value) { 112 int AsyncTCPSocketBase::GetOption(Socket::Option opt, int* value) {
112 return socket_->GetOption(opt, value); 113 return socket_->GetOption(opt, value);
113 } 114 }
114 115
115 int AsyncTCPSocketBase::SetOption(Socket::Option opt, int value) { 116 int AsyncTCPSocketBase::SetOption(Socket::Option opt, int value) {
116 return socket_->SetOption(opt, value); 117 return socket_->SetOption(opt, value);
117 } 118 }
118 119
119 int AsyncTCPSocketBase::GetError() const { 120 int AsyncTCPSocketBase::GetError() const {
120 return socket_->GetError(); 121 return socket_->GetError();
121 } 122 }
122 123
123 void AsyncTCPSocketBase::SetError(int error) { 124 void AsyncTCPSocketBase::SetError(int error) {
124 return socket_->SetError(error); 125 return socket_->SetError(error);
125 } 126 }
126 127
127 int AsyncTCPSocketBase::SendTo(const void *pv, size_t cb, 128 int AsyncTCPSocketBase::SendTo(const void *pv, size_t cb,
128 const SocketAddress& addr, 129 const SocketAddress& addr,
129 const rtc::PacketOptions& options) { 130 const rtc::PacketOptions& options) {
130 const SocketAddress& remote_address = GetRemoteAddress(); 131 const SocketAddress& remote_address = GetRemoteAddress();
131 if (addr == remote_address) 132 if (addr == remote_address)
132 return Send(pv, cb, options); 133 return Send(pv, cb, options);
133 // Remote address may be empty if there is a sudden network change. 134 // Remote address may be empty if there is a sudden network change.
134 ASSERT(remote_address.IsNil()); 135 RTC_DCHECK(remote_address.IsNil());
135 socket_->SetError(ENOTCONN); 136 socket_->SetError(ENOTCONN);
136 return -1; 137 return -1;
137 } 138 }
138 139
139 int AsyncTCPSocketBase::SendRaw(const void * pv, size_t cb) { 140 int AsyncTCPSocketBase::SendRaw(const void * pv, size_t cb) {
140 if (outpos_ + cb > outsize_) { 141 if (outpos_ + cb > outsize_) {
141 socket_->SetError(EMSGSIZE); 142 socket_->SetError(EMSGSIZE);
142 return -1; 143 return -1;
143 } 144 }
144 145
145 memcpy(outbuf_ + outpos_, pv, cb); 146 RTC_DCHECK(outbuf_.get());
147 memcpy(outbuf_.get() + outpos_, pv, cb);
146 outpos_ += cb; 148 outpos_ += cb;
147 149
148 return FlushOutBuffer(); 150 return FlushOutBuffer();
149 } 151 }
150 152
151 int AsyncTCPSocketBase::FlushOutBuffer() { 153 int AsyncTCPSocketBase::FlushOutBuffer() {
152 int res = socket_->Send(outbuf_, outpos_); 154 RTC_DCHECK(outbuf_.get());
155 int res = socket_->Send(outbuf_.get(), outpos_);
153 if (res <= 0) { 156 if (res <= 0) {
154 return res; 157 return res;
155 } 158 }
156 if (static_cast<size_t>(res) <= outpos_) { 159 if (static_cast<size_t>(res) <= outpos_) {
157 outpos_ -= res; 160 outpos_ -= res;
158 } else { 161 } else {
159 ASSERT(false); 162 RTC_NOTREACHED();
160 return -1; 163 return -1;
161 } 164 }
162 if (outpos_ > 0) { 165 if (outpos_ > 0) {
163 memmove(outbuf_, outbuf_ + res, outpos_); 166 memmove(outbuf_.get(), outbuf_.get() + res, outpos_);
164 } 167 }
165 return res; 168 return res;
166 } 169 }
167 170
168 void AsyncTCPSocketBase::AppendToOutBuffer(const void* pv, size_t cb) { 171 void AsyncTCPSocketBase::AppendToOutBuffer(const void* pv, size_t cb) {
169 ASSERT(outpos_ + cb < outsize_); 172 RTC_DCHECK(outpos_ + cb < outsize_);
170 memcpy(outbuf_ + outpos_, pv, cb); 173 RTC_DCHECK(outbuf_.get());
174 memcpy(outbuf_.get() + outpos_, pv, cb);
171 outpos_ += cb; 175 outpos_ += cb;
172 } 176 }
173 177
174 void AsyncTCPSocketBase::OnConnectEvent(AsyncSocket* socket) { 178 void AsyncTCPSocketBase::OnConnectEvent(AsyncSocket* socket) {
175 SignalConnect(this); 179 SignalConnect(this);
176 } 180 }
177 181
178 void AsyncTCPSocketBase::OnReadEvent(AsyncSocket* socket) { 182 void AsyncTCPSocketBase::OnReadEvent(AsyncSocket* socket) {
179 ASSERT(socket_.get() == socket); 183 RTC_DCHECK(socket_.get() == socket);
180 184
181 if (listen_) { 185 if (listen_) {
182 rtc::SocketAddress address; 186 rtc::SocketAddress address;
183 rtc::AsyncSocket* new_socket = socket->Accept(&address); 187 rtc::AsyncSocket* new_socket = socket->Accept(&address);
184 if (!new_socket) { 188 if (!new_socket) {
185 // TODO: Do something better like forwarding the error 189 // TODO: Do something better like forwarding the error
186 // to the user. 190 // to the user.
187 LOG(LS_ERROR) << "TCP accept failed with error " << socket_->GetError(); 191 LOG(LS_ERROR) << "TCP accept failed with error " << socket_->GetError();
188 return; 192 return;
189 } 193 }
190 194
191 HandleIncomingConnection(new_socket); 195 HandleIncomingConnection(new_socket);
192 196
193 // Prime a read event in case data is waiting. 197 // Prime a read event in case data is waiting.
194 new_socket->SignalReadEvent(new_socket); 198 new_socket->SignalReadEvent(new_socket);
195 } else { 199 } else {
196 int len = socket_->Recv(inbuf_ + inpos_, insize_ - inpos_); 200 RTC_DCHECK(inbuf_.get());
201 int len = socket_->Recv(inbuf_.get() + inpos_, insize_ - inpos_);
197 if (len < 0) { 202 if (len < 0) {
198 // TODO: Do something better like forwarding the error to the user. 203 // TODO: Do something better like forwarding the error to the user.
199 if (!socket_->IsBlocking()) { 204 if (!socket_->IsBlocking()) {
200 LOG(LS_ERROR) << "Recv() returned error: " << socket_->GetError(); 205 LOG(LS_ERROR) << "Recv() returned error: " << socket_->GetError();
201 } 206 }
202 return; 207 return;
203 } 208 }
204 209
205 inpos_ += len; 210 inpos_ += len;
206 211
207 ProcessInput(inbuf_, &inpos_); 212 ProcessInput(inbuf_.get(), &inpos_);
208 213
209 if (inpos_ >= insize_) { 214 if (inpos_ >= insize_) {
210 LOG(LS_ERROR) << "input buffer overflow"; 215 LOG(LS_ERROR) << "input buffer overflow";
211 ASSERT(false); 216 RTC_NOTREACHED();
212 inpos_ = 0; 217 inpos_ = 0;
213 } 218 }
214 } 219 }
215 } 220 }
216 221
217 void AsyncTCPSocketBase::OnWriteEvent(AsyncSocket* socket) { 222 void AsyncTCPSocketBase::OnWriteEvent(AsyncSocket* socket) {
218 ASSERT(socket_.get() == socket); 223 RTC_DCHECK(socket_.get() == socket);
219 224
220 if (outpos_ > 0) { 225 if (outpos_ > 0) {
221 FlushOutBuffer(); 226 FlushOutBuffer();
222 } 227 }
223 228
224 if (outpos_ == 0) { 229 if (outpos_ == 0) {
225 SignalReadyToSend(this); 230 SignalReadyToSend(this);
226 } 231 }
227 } 232 }
228 233
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 memmove(data, data + kPacketLenSize + pkt_len, *len); 299 memmove(data, data + kPacketLenSize + pkt_len, *len);
295 } 300 }
296 } 301 }
297 } 302 }
298 303
299 void AsyncTCPSocket::HandleIncomingConnection(AsyncSocket* socket) { 304 void AsyncTCPSocket::HandleIncomingConnection(AsyncSocket* socket) {
300 SignalNewConnection(this, new AsyncTCPSocket(socket, false)); 305 SignalNewConnection(this, new AsyncTCPSocket(socket, false));
301 } 306 }
302 307
303 } // namespace rtc 308 } // namespace rtc
OLDNEW
« no previous file with comments | « webrtc/base/asynctcpsocket.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698