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

Side by Side Diff: net/base/stream_listen_socket.cc

Issue 10161005: Add DefaultListenSocket. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix build on Windows Created 8 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « net/base/stream_listen_socket.h ('k') | net/base/tcp_listen_socket.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "build/build_config.h" 5 #include "net/base/stream_listen_socket.h"
6 6
7 #if defined(OS_WIN) 7 #if defined(OS_WIN)
8 // winsock2.h must be included first in order to ensure it is included before 8 // winsock2.h must be included first in order to ensure it is included before
9 // windows.h. 9 // windows.h.
10 #include <winsock2.h> 10 #include <winsock2.h>
11 #elif defined(OS_POSIX) 11 #elif defined(OS_POSIX)
12 #include <errno.h> 12 #include <errno.h>
13 #include <sys/types.h> 13 #include <sys/types.h>
14 #include <sys/socket.h> 14 #include <sys/socket.h>
15 #include <netinet/in.h> 15 #include <netinet/in.h>
16 #include <arpa/inet.h> 16 #include <arpa/inet.h>
17 #include "net/base/net_errors.h" 17 #include "net/base/net_errors.h"
18 #endif 18 #endif
19 19
20 #include "base/bind.h"
21 #include "base/eintr_wrapper.h" 20 #include "base/eintr_wrapper.h"
21 #include "base/logging.h"
22 #include "base/memory/ref_counted.h"
23 #include "base/memory/scoped_ptr.h"
22 #include "base/sys_byteorder.h" 24 #include "base/sys_byteorder.h"
23 #include "base/threading/platform_thread.h" 25 #include "base/threading/platform_thread.h"
26 #include "build/build_config.h"
24 #include "net/base/net_util.h" 27 #include "net/base/net_util.h"
25 #include "net/base/tcp_listen_socket.h" 28
29 using std::string;
26 30
27 #if defined(OS_WIN) 31 #if defined(OS_WIN)
28 typedef int socklen_t; 32 typedef int socklen_t;
29 #include "net/base/winsock_init.h" 33 #include "net/base/winsock_init.h"
30 #endif // defined(OS_WIN) 34 #endif // defined(OS_WIN)
31 35
32 namespace net { 36 namespace net {
33 37
34 namespace { 38 namespace {
35 39
(...skipping 22 matching lines...) Expand all
58 // has no significant state, -1 to never discard. 62 // has no significant state, -1 to never discard.
59 -1, 63 -1,
60 64
61 // Don't use initial delay unless the last request was an error. 65 // Don't use initial delay unless the last request was an error.
62 false, 66 false,
63 }; 67 };
64 68
65 } // namespace 69 } // namespace
66 70
67 #if defined(OS_WIN) 71 #if defined(OS_WIN)
68 const SOCKET TCPListenSocket::kInvalidSocket = INVALID_SOCKET; 72 const SOCKET StreamListenSocket::kInvalidSocket = INVALID_SOCKET;
69 const int TCPListenSocket::kSocketError = SOCKET_ERROR; 73 const int StreamListenSocket::kSocketError = SOCKET_ERROR;
70 #elif defined(OS_POSIX) 74 #elif defined(OS_POSIX)
71 const SOCKET TCPListenSocket::kInvalidSocket = -1; 75 const SOCKET StreamListenSocket::kInvalidSocket = -1;
72 const int TCPListenSocket::kSocketError = -1; 76 const int StreamListenSocket::kSocketError = -1;
73 #endif 77 #endif
74 78
75 TCPListenSocket* TCPListenSocket::CreateAndListen( 79 StreamListenSocket::StreamListenSocket(SOCKET s,
76 const std::string& ip, int port, ListenSocket::ListenSocketDelegate *del) { 80 StreamListenSocket::Delegate* del)
77 SOCKET s = CreateAndBind(ip, port); 81 : socket_delegate_(del),
78 if (s == kInvalidSocket) {
79 // TODO(erikkay): error handling
80 } else {
81 TCPListenSocket* sock = new TCPListenSocket(s, del);
82 sock->Listen();
83 return sock;
84 }
85 return NULL;
86 }
87
88 void TCPListenSocket::PauseReads() {
89 DCHECK(!reads_paused_);
90 reads_paused_ = true;
91 }
92
93 void TCPListenSocket::ResumeReads() {
94 DCHECK(reads_paused_);
95 reads_paused_ = false;
96 if (has_pending_reads_) {
97 has_pending_reads_ = false;
98 Read();
99 }
100 }
101
102 TCPListenSocket::TCPListenSocket(SOCKET s,
103 ListenSocket::ListenSocketDelegate *del)
104 : ListenSocket(del),
105 socket_(s), 82 socket_(s),
106 reads_paused_(false), 83 reads_paused_(false),
107 has_pending_reads_(false), 84 has_pending_reads_(false),
108 send_pending_size_(0), 85 send_pending_size_(0),
109 send_error_(false), 86 send_error_(false),
110 send_backoff_(&kSendBackoffPolicy) { 87 send_backoff_(&kSendBackoffPolicy) {
111 #if defined(OS_WIN) 88 #if defined(OS_WIN)
112 socket_event_ = WSACreateEvent(); 89 socket_event_ = WSACreateEvent();
113 // TODO(ibrar): error handling in case of socket_event_ == WSA_INVALID_EVENT 90 // TODO(ibrar): error handling in case of socket_event_ == WSA_INVALID_EVENT.
114 WatchSocket(NOT_WAITING); 91 WatchSocket(NOT_WAITING);
115 #elif defined(OS_POSIX) 92 #elif defined(OS_POSIX)
116 wait_state_ = NOT_WAITING; 93 wait_state_ = NOT_WAITING;
117 #endif 94 #endif
118 } 95 }
119 96
120 TCPListenSocket::~TCPListenSocket() { 97 StreamListenSocket::~StreamListenSocket() {
121 #if defined(OS_WIN) 98 #if defined(OS_WIN)
122 if (socket_event_) { 99 if (socket_event_) {
123 WSACloseEvent(socket_event_); 100 WSACloseEvent(socket_event_);
124 socket_event_ = WSA_INVALID_EVENT; 101 socket_event_ = WSA_INVALID_EVENT;
125 } 102 }
126 #endif 103 #endif
127 CloseSocket(socket_); 104 CloseSocket(socket_);
128 } 105 }
129 106
130 SOCKET TCPListenSocket::CreateAndBind(const std::string& ip, int port) { 107 void StreamListenSocket::Send(const char* bytes, int len,
131 #if defined(OS_WIN) 108 bool append_linefeed) {
132 EnsureWinsockInit(); 109 SendInternal(bytes, len);
133 #endif 110 if (append_linefeed)
134 111 SendInternal("\r\n", 2);
135 SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
136 if (s != kInvalidSocket) {
137 #if defined(OS_POSIX)
138 // Allow rapid reuse.
139 static const int kOn = 1;
140 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &kOn, sizeof(kOn));
141 #endif
142 sockaddr_in addr;
143 memset(&addr, 0, sizeof(addr));
144 addr.sin_family = AF_INET;
145 addr.sin_addr.s_addr = inet_addr(ip.c_str());
146 addr.sin_port = base::HostToNet16(port);
147 if (bind(s, reinterpret_cast<sockaddr*>(&addr), sizeof(addr))) {
148 #if defined(OS_WIN)
149 closesocket(s);
150 #elif defined(OS_POSIX)
151 close(s);
152 #endif
153 s = kInvalidSocket;
154 }
155 }
156 return s;
157 } 112 }
158 113
159 SOCKET TCPListenSocket::Accept(SOCKET s) { 114 void StreamListenSocket::Send(const string& str, bool append_linefeed) {
160 sockaddr_in from; 115 Send(str.data(), static_cast<int>(str.length()), append_linefeed);
161 socklen_t from_len = sizeof(from); 116 }
162 SOCKET conn = 117
163 HANDLE_EINTR(accept(s, reinterpret_cast<sockaddr*>(&from), &from_len)); 118 SOCKET StreamListenSocket::AcceptSocket() {
164 if (conn != kInvalidSocket) { 119 SOCKET conn = HANDLE_EINTR(accept(socket_, NULL, NULL));
120 if (conn == kInvalidSocket)
121 LOG(ERROR) << "Error accepting connection.";
122 else
165 SetNonBlocking(conn); 123 SetNonBlocking(conn);
166 }
167 return conn; 124 return conn;
168 } 125 }
169 126
170 void TCPListenSocket::SendInternal(const char* bytes, int len) { 127 void StreamListenSocket::SendInternal(const char* bytes, int len) {
171 DCHECK(bytes); 128 DCHECK(bytes);
172 if (!bytes || len <= 0) 129 if (!bytes || len <= 0)
173 return; 130 return;
174 131
175 if (send_error_) 132 if (send_error_)
176 return; 133 return;
177 134
178 if (send_pending_size_ + len > kMaxSendBufSize) { 135 if (send_pending_size_ + len > kMaxSendBufSize) {
179 LOG(ERROR) << "send failed: buffer overrun"; 136 LOG(ERROR) << "send failed: buffer overrun";
180 send_buffers_.clear(); 137 send_buffers_.clear();
181 send_pending_size_ = 0; 138 send_pending_size_ = 0;
182 send_error_ = true; 139 send_error_ = true;
183 return; 140 return;
184 } 141 }
185 142
186 scoped_refptr<IOBuffer> buffer(new IOBuffer(len)); 143 scoped_refptr<IOBuffer> buffer(new IOBuffer(len));
187 memcpy(buffer->data(), bytes, len); 144 memcpy(buffer->data(), bytes, len);
188 send_buffers_.push_back(new DrainableIOBuffer(buffer, len)); 145 send_buffers_.push_back(new DrainableIOBuffer(buffer, len));
189 send_pending_size_ += len; 146 send_pending_size_ += len;
190 147
191 if (!send_timer_.IsRunning()) 148 if (!send_timer_.IsRunning())
192 SendData(); 149 SendData();
193 } 150 }
194 151
195 void TCPListenSocket::Listen() { 152 void StreamListenSocket::Listen() {
196 int backlog = 10; // TODO(erikkay): maybe don't allow any backlog? 153 int backlog = 10; // TODO(erikkay): maybe don't allow any backlog?
197 listen(socket_, backlog); 154 if (listen(socket_, backlog) == -1) {
198 // TODO(erikkay): error handling 155 // TODO(erikkay): error handling.
156 LOG(ERROR) << "Could not listen on socket.";
157 return;
158 }
199 #if defined(OS_POSIX) 159 #if defined(OS_POSIX)
200 WatchSocket(WAITING_ACCEPT); 160 WatchSocket(WAITING_ACCEPT);
201 #endif 161 #endif
202 } 162 }
203 163
204 void TCPListenSocket::Accept() { 164 void StreamListenSocket::Read() {
205 SOCKET conn = Accept(socket_); 165 char buf[kReadBufSize + 1]; // +1 for null termination.
206 if (conn != kInvalidSocket) {
207 scoped_refptr<TCPListenSocket> sock(
208 new TCPListenSocket(conn, socket_delegate_));
209 // it's up to the delegate to AddRef if it wants to keep it around
210 #if defined(OS_POSIX)
211 sock->WatchSocket(WAITING_READ);
212 #endif
213 socket_delegate_->DidAccept(this, sock);
214 } else {
215 // TODO(ibrar): some error handling required here
216 }
217 }
218
219 void TCPListenSocket::Read() {
220 char buf[kReadBufSize + 1]; // +1 for null termination
221 int len; 166 int len;
222 do { 167 do {
223 len = HANDLE_EINTR(recv(socket_, buf, kReadBufSize, 0)); 168 len = HANDLE_EINTR(recv(socket_, buf, kReadBufSize, 0));
224 if (len == kSocketError) { 169 if (len == kSocketError) {
225 #if defined(OS_WIN) 170 #if defined(OS_WIN)
226 int err = WSAGetLastError(); 171 int err = WSAGetLastError();
227 if (err == WSAEWOULDBLOCK) { 172 if (err == WSAEWOULDBLOCK) {
228 #elif defined(OS_POSIX) 173 #elif defined(OS_POSIX)
229 if (errno == EWOULDBLOCK || errno == EAGAIN) { 174 if (errno == EWOULDBLOCK || errno == EAGAIN) {
230 #endif 175 #endif
231 break; 176 break;
232 } else { 177 } else {
233 // TODO(ibrar): some error handling required here 178 // TODO(ibrar): some error handling required here.
234 break; 179 break;
235 } 180 }
236 } else if (len == 0) { 181 } else if (len == 0) {
237 // In Windows, Close() is called by OnObjectSignaled. In POSIX, we need 182 // In Windows, Close() is called by OnObjectSignaled. In POSIX, we need
238 // to call it here. 183 // to call it here.
239 #if defined(OS_POSIX) 184 #if defined(OS_POSIX)
240 Close(); 185 Close();
241 #endif 186 #endif
242 } else { 187 } else {
243 // TODO(ibrar): maybe change DidRead to take a length instead 188 // TODO(ibrar): maybe change DidRead to take a length instead.
244 DCHECK_GT(len, 0); 189 DCHECK_GT(len, 0);
245 DCHECK_LE(len, kReadBufSize); 190 DCHECK_LE(len, kReadBufSize);
246 buf[len] = 0; // already create a buffer with +1 length 191 buf[len] = 0; // Already create a buffer with +1 length.
247 socket_delegate_->DidRead(this, buf, len); 192 socket_delegate_->DidRead(this, buf, len);
248 } 193 }
249 } while (len == kReadBufSize); 194 } while (len == kReadBufSize);
250 } 195 }
251 196
252 void TCPListenSocket::Close() { 197 void StreamListenSocket::Close() {
253 #if defined(OS_POSIX) 198 #if defined(OS_POSIX)
254 if (wait_state_ == NOT_WAITING) 199 if (wait_state_ == NOT_WAITING)
255 return; 200 return;
256 wait_state_ = NOT_WAITING; 201 wait_state_ = NOT_WAITING;
257 #endif 202 #endif
258 UnwatchSocket(); 203 UnwatchSocket();
259 socket_delegate_->DidClose(this); 204 socket_delegate_->DidClose(this);
260 } 205 }
261 206
262 void TCPListenSocket::CloseSocket(SOCKET s) { 207 void StreamListenSocket::CloseSocket(SOCKET s) {
263 if (s && s != kInvalidSocket) { 208 if (s && s != kInvalidSocket) {
264 UnwatchSocket(); 209 UnwatchSocket();
265 #if defined(OS_WIN) 210 #if defined(OS_WIN)
266 closesocket(s); 211 closesocket(s);
267 #elif defined(OS_POSIX) 212 #elif defined(OS_POSIX)
268 close(s); 213 close(s);
269 #endif 214 #endif
270 } 215 }
271 } 216 }
272 217
273 void TCPListenSocket::WatchSocket(WaitState state) { 218 void StreamListenSocket::WatchSocket(WaitState state) {
274 #if defined(OS_WIN) 219 #if defined(OS_WIN)
275 WSAEventSelect(socket_, socket_event_, FD_ACCEPT | FD_CLOSE | FD_READ); 220 WSAEventSelect(socket_, socket_event_, FD_ACCEPT | FD_CLOSE | FD_READ);
276 watcher_.StartWatching(socket_event_, this); 221 watcher_.StartWatching(socket_event_, this);
277 #elif defined(OS_POSIX) 222 #elif defined(OS_POSIX)
278 // Implicitly calls StartWatchingFileDescriptor(). 223 // Implicitly calls StartWatchingFileDescriptor().
279 MessageLoopForIO::current()->WatchFileDescriptor( 224 MessageLoopForIO::current()->WatchFileDescriptor(
280 socket_, true, MessageLoopForIO::WATCH_READ, &watcher_, this); 225 socket_, true, MessageLoopForIO::WATCH_READ, &watcher_, this);
281 wait_state_ = state; 226 wait_state_ = state;
282 #endif 227 #endif
283 } 228 }
284 229
285 void TCPListenSocket::UnwatchSocket() { 230 void StreamListenSocket::UnwatchSocket() {
286 #if defined(OS_WIN) 231 #if defined(OS_WIN)
287 watcher_.StopWatching(); 232 watcher_.StopWatching();
288 #elif defined(OS_POSIX) 233 #elif defined(OS_POSIX)
289 watcher_.StopWatchingFileDescriptor(); 234 watcher_.StopWatchingFileDescriptor();
290 #endif 235 #endif
291 } 236 }
292 237
293 // TODO(ibrar): We can add these functions into OS dependent files 238 // TODO(ibrar): We can add these functions into OS dependent files.
294 #if defined(OS_WIN) 239 #if defined(OS_WIN)
295 // MessageLoop watcher callback 240 // MessageLoop watcher callback.
296 void TCPListenSocket::OnObjectSignaled(HANDLE object) { 241 void StreamListenSocket::OnObjectSignaled(HANDLE object) {
297 WSANETWORKEVENTS ev; 242 WSANETWORKEVENTS ev;
298 if (kSocketError == WSAEnumNetworkEvents(socket_, socket_event_, &ev)) { 243 if (kSocketError == WSAEnumNetworkEvents(socket_, socket_event_, &ev)) {
299 // TODO 244 // TODO
300 return; 245 return;
301 } 246 }
302 247
303 // The object was reset by WSAEnumNetworkEvents. Watch for the next signal. 248 // The object was reset by WSAEnumNetworkEvents. Watch for the next signal.
304 watcher_.StartWatching(object, this); 249 watcher_.StartWatching(object, this);
305 250
306 if (ev.lNetworkEvents == 0) { 251 if (ev.lNetworkEvents == 0) {
307 // Occasionally the event is set even though there is no new data. 252 // Occasionally the event is set even though there is no new data.
308 // The net seems to think that this is ignorable. 253 // The net seems to think that this is ignorable.
309 return; 254 return;
310 } 255 }
311 if (ev.lNetworkEvents & FD_ACCEPT) { 256 if (ev.lNetworkEvents & FD_ACCEPT) {
312 Accept(); 257 Accept();
313 } 258 }
314 if (ev.lNetworkEvents & FD_READ) { 259 if (ev.lNetworkEvents & FD_READ) {
315 if (reads_paused_) { 260 if (reads_paused_) {
316 has_pending_reads_ = true; 261 has_pending_reads_ = true;
317 } else { 262 } else {
318 Read(); 263 Read();
319 } 264 }
320 } 265 }
321 if (ev.lNetworkEvents & FD_CLOSE) { 266 if (ev.lNetworkEvents & FD_CLOSE) {
322 Close(); 267 Close();
323 } 268 }
324 } 269 }
325 #elif defined(OS_POSIX) 270 #elif defined(OS_POSIX)
326 void TCPListenSocket::OnFileCanReadWithoutBlocking(int fd) { 271 void StreamListenSocket::OnFileCanReadWithoutBlocking(int fd) {
327 switch (wait_state_) { 272 switch (wait_state_) {
328 case WAITING_ACCEPT: 273 case WAITING_ACCEPT:
329 Accept(); 274 Accept();
330 break; 275 break;
331 case WAITING_READ: 276 case WAITING_READ:
332 if (reads_paused_) { 277 if (reads_paused_) {
333 has_pending_reads_ = true; 278 has_pending_reads_ = true;
334 } else { 279 } else {
335 Read(); 280 Read();
336 } 281 }
337 break; 282 break;
338 default: 283 default:
339 // Close() is called by Read() in the Linux case. 284 // Close() is called by Read() in the Linux case.
340 NOTREACHED(); 285 NOTREACHED();
341 break; 286 break;
342 } 287 }
343 } 288 }
344 289
345 void TCPListenSocket::OnFileCanWriteWithoutBlocking(int fd) { 290 void StreamListenSocket::OnFileCanWriteWithoutBlocking(int fd) {
346 // MessagePumpLibevent callback, we don't listen for write events 291 // MessagePumpLibevent callback, we don't listen for write events
347 // so we shouldn't ever reach here. 292 // so we shouldn't ever reach here.
348 NOTREACHED(); 293 NOTREACHED();
349 } 294 }
350 295
351 #endif 296 #endif
352 297
353 void TCPListenSocket::SendData() { 298 void StreamListenSocket::PauseReads() {
299 DCHECK(!reads_paused_);
300 reads_paused_ = true;
301 }
302
303 void StreamListenSocket::ResumeReads() {
304 DCHECK(reads_paused_);
305 reads_paused_ = false;
306 if (has_pending_reads_) {
307 has_pending_reads_ = false;
308 Read();
309 }
310 }
311
312 void StreamListenSocket::SendData() {
354 DCHECK(!send_buffers_.empty()); 313 DCHECK(!send_buffers_.empty());
355 314
356 int total_sent = 0; 315 int total_sent = 0;
357 316
358 // Send data until all buffers have been sent or a call would block. 317 // Send data until all buffers have been sent or a call would block.
359 while (!send_buffers_.empty()) { 318 while (!send_buffers_.empty()) {
360 scoped_refptr<DrainableIOBuffer> buffer = send_buffers_.front(); 319 scoped_refptr<DrainableIOBuffer> buffer = send_buffers_.front();
361 320
362 int len_left = buffer->BytesRemaining(); 321 int len_left = buffer->BytesRemaining();
363 int sent = HANDLE_EINTR(send(socket_, buffer->data(), len_left, 0)); 322 int sent = HANDLE_EINTR(send(socket_, buffer->data(), len_left, 0));
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 // Clear the back-off delay. 357 // Clear the back-off delay.
399 send_backoff_.Reset(); 358 send_backoff_.Reset();
400 } else { 359 } else {
401 // Increase the back-off delay. 360 // Increase the back-off delay.
402 send_backoff_.InformOfRequest(false); 361 send_backoff_.InformOfRequest(false);
403 } 362 }
404 363
405 if (!send_buffers_.empty()) { 364 if (!send_buffers_.empty()) {
406 DCHECK(!send_timer_.IsRunning()); 365 DCHECK(!send_timer_.IsRunning());
407 send_timer_.Start(FROM_HERE, send_backoff_.GetTimeUntilRelease(), 366 send_timer_.Start(FROM_HERE, send_backoff_.GetTimeUntilRelease(),
408 this, &TCPListenSocket::SendData); 367 this, &StreamListenSocket::SendData);
409 } 368 }
410 } 369 }
411 370
412 } // namespace net 371 } // namespace net
OLDNEW
« no previous file with comments | « net/base/stream_listen_socket.h ('k') | net/base/tcp_listen_socket.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698