OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "net/socket/tcp_client_socket_libevent.h" | 5 #include "net/socket/tcp_client_socket_libevent.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <netdb.h> | 9 #include <netdb.h> |
10 #include <sys/socket.h> | 10 #include <sys/socket.h> |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 waiting_connect_(false), | 130 waiting_connect_(false), |
131 read_watcher_(this), | 131 read_watcher_(this), |
132 write_watcher_(this), | 132 write_watcher_(this), |
133 read_callback_(NULL), | 133 read_callback_(NULL), |
134 write_callback_(NULL), | 134 write_callback_(NULL), |
135 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) { | 135 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) { |
136 } | 136 } |
137 | 137 |
138 TCPClientSocketLibevent::~TCPClientSocketLibevent() { | 138 TCPClientSocketLibevent::~TCPClientSocketLibevent() { |
139 Disconnect(); | 139 Disconnect(); |
140 net_log_.AddEvent(NetLog::TYPE_TCP_SOCKET_DONE); | 140 net_log_.AddEvent(NetLog::TYPE_TCP_SOCKET_DONE, NULL); |
141 } | 141 } |
142 | 142 |
143 int TCPClientSocketLibevent::Connect(CompletionCallback* callback) { | 143 int TCPClientSocketLibevent::Connect(CompletionCallback* callback) { |
144 // If already connected, then just return OK. | 144 // If already connected, then just return OK. |
145 if (socket_ != kInvalidSocket) | 145 if (socket_ != kInvalidSocket) |
146 return OK; | 146 return OK; |
147 | 147 |
148 DCHECK(!waiting_connect_); | 148 DCHECK(!waiting_connect_); |
149 | 149 |
150 TRACE_EVENT_BEGIN("socket.connect", this, ""); | 150 TRACE_EVENT_BEGIN("socket.connect", this, ""); |
151 | 151 |
152 net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT); | 152 net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT, NULL); |
153 | 153 |
154 int rv = DoConnect(); | 154 int rv = DoConnect(); |
155 | 155 |
156 if (rv == ERR_IO_PENDING) { | 156 if (rv == ERR_IO_PENDING) { |
157 // Synchronous operation not supported. | 157 // Synchronous operation not supported. |
158 DCHECK(callback); | 158 DCHECK(callback); |
159 | 159 |
160 waiting_connect_ = true; | 160 waiting_connect_ = true; |
161 write_callback_ = callback; | 161 write_callback_ = callback; |
162 } else { | 162 } else { |
163 TRACE_EVENT_END("socket.connect", this, ""); | 163 TRACE_EVENT_END("socket.connect", this, ""); |
164 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT); | 164 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, NULL); |
165 } | 165 } |
166 | 166 |
167 return rv; | 167 return rv; |
168 } | 168 } |
169 | 169 |
170 int TCPClientSocketLibevent::DoConnect() { | 170 int TCPClientSocketLibevent::DoConnect() { |
171 while (true) { | 171 while (true) { |
172 DCHECK(current_ai_); | 172 DCHECK(current_ai_); |
173 | 173 |
174 int rv = CreateSocket(current_ai_); | 174 int rv = CreateSocket(current_ai_); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 DCHECK(!waiting_connect_); | 270 DCHECK(!waiting_connect_); |
271 DCHECK(!read_callback_); | 271 DCHECK(!read_callback_); |
272 // Synchronous operation not supported | 272 // Synchronous operation not supported |
273 DCHECK(callback); | 273 DCHECK(callback); |
274 DCHECK_GT(buf_len, 0); | 274 DCHECK_GT(buf_len, 0); |
275 | 275 |
276 TRACE_EVENT_BEGIN("socket.read", this, ""); | 276 TRACE_EVENT_BEGIN("socket.read", this, ""); |
277 int nread = HANDLE_EINTR(read(socket_, buf->data(), buf_len)); | 277 int nread = HANDLE_EINTR(read(socket_, buf->data(), buf_len)); |
278 if (nread >= 0) { | 278 if (nread >= 0) { |
279 TRACE_EVENT_END("socket.read", this, StringPrintf("%d bytes", nread)); | 279 TRACE_EVENT_END("socket.read", this, StringPrintf("%d bytes", nread)); |
280 net_log_.AddEventWithInteger(NetLog::TYPE_SOCKET_BYTES_RECEIVED, | 280 net_log_.AddEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, |
281 "num_bytes", nread); | 281 new NetLogIntegerParameter("num_bytes", nread)); |
282 return nread; | 282 return nread; |
283 } | 283 } |
284 if (errno != EAGAIN && errno != EWOULDBLOCK) { | 284 if (errno != EAGAIN && errno != EWOULDBLOCK) { |
285 DLOG(INFO) << "read failed, errno " << errno; | 285 DLOG(INFO) << "read failed, errno " << errno; |
286 return MapPosixError(errno); | 286 return MapPosixError(errno); |
287 } | 287 } |
288 | 288 |
289 if (!MessageLoopForIO::current()->WatchFileDescriptor( | 289 if (!MessageLoopForIO::current()->WatchFileDescriptor( |
290 socket_, true, MessageLoopForIO::WATCH_READ, | 290 socket_, true, MessageLoopForIO::WATCH_READ, |
291 &read_socket_watcher_, &read_watcher_)) { | 291 &read_socket_watcher_, &read_watcher_)) { |
(...skipping 14 matching lines...) Expand all Loading... |
306 DCHECK(!waiting_connect_); | 306 DCHECK(!waiting_connect_); |
307 DCHECK(!write_callback_); | 307 DCHECK(!write_callback_); |
308 // Synchronous operation not supported | 308 // Synchronous operation not supported |
309 DCHECK(callback); | 309 DCHECK(callback); |
310 DCHECK_GT(buf_len, 0); | 310 DCHECK_GT(buf_len, 0); |
311 | 311 |
312 TRACE_EVENT_BEGIN("socket.write", this, ""); | 312 TRACE_EVENT_BEGIN("socket.write", this, ""); |
313 int nwrite = HANDLE_EINTR(write(socket_, buf->data(), buf_len)); | 313 int nwrite = HANDLE_EINTR(write(socket_, buf->data(), buf_len)); |
314 if (nwrite >= 0) { | 314 if (nwrite >= 0) { |
315 TRACE_EVENT_END("socket.write", this, StringPrintf("%d bytes", nwrite)); | 315 TRACE_EVENT_END("socket.write", this, StringPrintf("%d bytes", nwrite)); |
316 net_log_.AddEventWithInteger(NetLog::TYPE_SOCKET_BYTES_SENT, | 316 net_log_.AddEvent(NetLog::TYPE_SOCKET_BYTES_SENT, |
317 "num_bytes", nwrite); | 317 new NetLogIntegerParameter("num_bytes", nwrite)); |
318 return nwrite; | 318 return nwrite; |
319 } | 319 } |
320 if (errno != EAGAIN && errno != EWOULDBLOCK) | 320 if (errno != EAGAIN && errno != EWOULDBLOCK) |
321 return MapPosixError(errno); | 321 return MapPosixError(errno); |
322 | 322 |
323 if (!MessageLoopForIO::current()->WatchFileDescriptor( | 323 if (!MessageLoopForIO::current()->WatchFileDescriptor( |
324 socket_, true, MessageLoopForIO::WATCH_WRITE, | 324 socket_, true, MessageLoopForIO::WATCH_WRITE, |
325 &write_socket_watcher_, &write_watcher_)) { | 325 &write_socket_watcher_, &write_watcher_)) { |
326 DLOG(INFO) << "WatchFileDescriptor failed on write, errno " << errno; | 326 DLOG(INFO) << "WatchFileDescriptor failed on write, errno " << errno; |
327 return MapPosixError(errno); | 327 return MapPosixError(errno); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
401 | 401 |
402 if (os_error == EINPROGRESS || os_error == EALREADY) { | 402 if (os_error == EINPROGRESS || os_error == EALREADY) { |
403 NOTREACHED(); // This indicates a bug in libevent or our code. | 403 NOTREACHED(); // This indicates a bug in libevent or our code. |
404 result = ERR_IO_PENDING; | 404 result = ERR_IO_PENDING; |
405 } else if (current_ai_->ai_next && ShouldTryNextAddress(os_error)) { | 405 } else if (current_ai_->ai_next && ShouldTryNextAddress(os_error)) { |
406 // This address failed, try next one in list. | 406 // This address failed, try next one in list. |
407 const addrinfo* next = current_ai_->ai_next; | 407 const addrinfo* next = current_ai_->ai_next; |
408 Disconnect(); | 408 Disconnect(); |
409 current_ai_ = next; | 409 current_ai_ = next; |
410 TRACE_EVENT_END("socket.connect", this, ""); | 410 TRACE_EVENT_END("socket.connect", this, ""); |
411 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT); | 411 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, NULL); |
412 result = Connect(write_callback_); | 412 result = Connect(write_callback_); |
413 } else { | 413 } else { |
414 result = MapConnectError(os_error); | 414 result = MapConnectError(os_error); |
415 bool ok = write_socket_watcher_.StopWatchingFileDescriptor(); | 415 bool ok = write_socket_watcher_.StopWatchingFileDescriptor(); |
416 DCHECK(ok); | 416 DCHECK(ok); |
417 waiting_connect_ = false; | 417 waiting_connect_ = false; |
418 TRACE_EVENT_END("socket.connect", this, ""); | 418 TRACE_EVENT_END("socket.connect", this, ""); |
419 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT); | 419 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, NULL); |
420 } | 420 } |
421 | 421 |
422 if (result != ERR_IO_PENDING) { | 422 if (result != ERR_IO_PENDING) { |
423 DoWriteCallback(result); | 423 DoWriteCallback(result); |
424 } | 424 } |
425 } | 425 } |
426 | 426 |
427 void TCPClientSocketLibevent::DidCompleteRead() { | 427 void TCPClientSocketLibevent::DidCompleteRead() { |
428 int bytes_transferred; | 428 int bytes_transferred; |
429 bytes_transferred = HANDLE_EINTR(read(socket_, read_buf_->data(), | 429 bytes_transferred = HANDLE_EINTR(read(socket_, read_buf_->data(), |
430 read_buf_len_)); | 430 read_buf_len_)); |
431 | 431 |
432 int result; | 432 int result; |
433 if (bytes_transferred >= 0) { | 433 if (bytes_transferred >= 0) { |
434 TRACE_EVENT_END("socket.read", this, | 434 TRACE_EVENT_END("socket.read", this, |
435 StringPrintf("%d bytes", bytes_transferred)); | 435 StringPrintf("%d bytes", bytes_transferred)); |
436 result = bytes_transferred; | 436 result = bytes_transferred; |
437 net_log_.AddEventWithInteger(NetLog::TYPE_SOCKET_BYTES_RECEIVED, | 437 net_log_.AddEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, |
438 "num_bytes", result); | 438 new NetLogIntegerParameter("num_bytes", result)); |
439 } else { | 439 } else { |
440 result = MapPosixError(errno); | 440 result = MapPosixError(errno); |
441 } | 441 } |
442 | 442 |
443 if (result != ERR_IO_PENDING) { | 443 if (result != ERR_IO_PENDING) { |
444 read_buf_ = NULL; | 444 read_buf_ = NULL; |
445 read_buf_len_ = 0; | 445 read_buf_len_ = 0; |
446 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); | 446 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); |
447 DCHECK(ok); | 447 DCHECK(ok); |
448 DoReadCallback(result); | 448 DoReadCallback(result); |
449 } | 449 } |
450 } | 450 } |
451 | 451 |
452 void TCPClientSocketLibevent::DidCompleteWrite() { | 452 void TCPClientSocketLibevent::DidCompleteWrite() { |
453 int bytes_transferred; | 453 int bytes_transferred; |
454 bytes_transferred = HANDLE_EINTR(write(socket_, write_buf_->data(), | 454 bytes_transferred = HANDLE_EINTR(write(socket_, write_buf_->data(), |
455 write_buf_len_)); | 455 write_buf_len_)); |
456 | 456 |
457 int result; | 457 int result; |
458 if (bytes_transferred >= 0) { | 458 if (bytes_transferred >= 0) { |
459 result = bytes_transferred; | 459 result = bytes_transferred; |
460 TRACE_EVENT_END("socket.write", this, | 460 TRACE_EVENT_END("socket.write", this, |
461 StringPrintf("%d bytes", bytes_transferred)); | 461 StringPrintf("%d bytes", bytes_transferred)); |
462 net_log_.AddEventWithInteger(NetLog::TYPE_SOCKET_BYTES_SENT, | 462 net_log_.AddEvent(NetLog::TYPE_SOCKET_BYTES_SENT, |
463 "num_bytes", result); | 463 new NetLogIntegerParameter("num_bytes", result)); |
464 } else { | 464 } else { |
465 result = MapPosixError(errno); | 465 result = MapPosixError(errno); |
466 } | 466 } |
467 | 467 |
468 if (result != ERR_IO_PENDING) { | 468 if (result != ERR_IO_PENDING) { |
469 write_buf_ = NULL; | 469 write_buf_ = NULL; |
470 write_buf_len_ = 0; | 470 write_buf_len_ = 0; |
471 write_socket_watcher_.StopWatchingFileDescriptor(); | 471 write_socket_watcher_.StopWatchingFileDescriptor(); |
472 DoWriteCallback(result); | 472 DoWriteCallback(result); |
473 } | 473 } |
474 } | 474 } |
475 | 475 |
476 int TCPClientSocketLibevent::GetPeerAddress(AddressList* address) const { | 476 int TCPClientSocketLibevent::GetPeerAddress(AddressList* address) const { |
477 DCHECK(address); | 477 DCHECK(address); |
478 if (!current_ai_) | 478 if (!current_ai_) |
479 return ERR_UNEXPECTED; | 479 return ERR_UNEXPECTED; |
480 address->Copy(current_ai_, false); | 480 address->Copy(current_ai_, false); |
481 return OK; | 481 return OK; |
482 } | 482 } |
483 | 483 |
484 } // namespace net | 484 } // namespace net |
OLD | NEW |