| 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_win.h" | 5 #include "net/socket/tcp_client_socket_win.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
| 9 #include "base/memory_debug.h" | 9 #include "base/memory_debug.h" |
| 10 #include "base/stats_counters.h" | 10 #include "base/stats_counters.h" |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) { | 285 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) { |
| 286 EnsureWinsockInit(); | 286 EnsureWinsockInit(); |
| 287 } | 287 } |
| 288 | 288 |
| 289 TCPClientSocketWin::~TCPClientSocketWin() { | 289 TCPClientSocketWin::~TCPClientSocketWin() { |
| 290 Disconnect(); | 290 Disconnect(); |
| 291 net_log_.AddEvent(NetLog::TYPE_TCP_SOCKET_DONE, NULL); | 291 net_log_.AddEvent(NetLog::TYPE_TCP_SOCKET_DONE, NULL); |
| 292 } | 292 } |
| 293 | 293 |
| 294 int TCPClientSocketWin::Connect(CompletionCallback* callback) { | 294 int TCPClientSocketWin::Connect(CompletionCallback* callback) { |
| 295 DCHECK(CalledOnValidThread()); |
| 296 |
| 295 // If already connected, then just return OK. | 297 // If already connected, then just return OK. |
| 296 if (socket_ != INVALID_SOCKET) | 298 if (socket_ != INVALID_SOCKET) |
| 297 return OK; | 299 return OK; |
| 298 | 300 |
| 299 static StatsCounter connects("tcp.connect"); | 301 static StatsCounter connects("tcp.connect"); |
| 300 connects.Increment(); | 302 connects.Increment(); |
| 301 | 303 |
| 302 TRACE_EVENT_BEGIN("socket.connect", this, ""); | 304 TRACE_EVENT_BEGIN("socket.connect", this, ""); |
| 303 | 305 |
| 304 net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT, NULL); | 306 net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT, NULL); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 LOG(ERROR) << "connect failed: " << os_error; | 363 LOG(ERROR) << "connect failed: " << os_error; |
| 362 return MapConnectError(os_error); | 364 return MapConnectError(os_error); |
| 363 } | 365 } |
| 364 } | 366 } |
| 365 | 367 |
| 366 core_->WatchForRead(); | 368 core_->WatchForRead(); |
| 367 return ERR_IO_PENDING; | 369 return ERR_IO_PENDING; |
| 368 } | 370 } |
| 369 | 371 |
| 370 void TCPClientSocketWin::Disconnect() { | 372 void TCPClientSocketWin::Disconnect() { |
| 373 DCHECK(CalledOnValidThread()); |
| 374 |
| 371 if (socket_ == INVALID_SOCKET) | 375 if (socket_ == INVALID_SOCKET) |
| 372 return; | 376 return; |
| 373 | 377 |
| 374 TRACE_EVENT_INSTANT("socket.disconnect", this, ""); | 378 TRACE_EVENT_INSTANT("socket.disconnect", this, ""); |
| 375 | 379 |
| 376 // Note: don't use CancelIo to cancel pending IO because it doesn't work | 380 // Note: don't use CancelIo to cancel pending IO because it doesn't work |
| 377 // when there is a Winsock layered service provider. | 381 // when there is a Winsock layered service provider. |
| 378 | 382 |
| 379 // In most socket implementations, closing a socket results in a graceful | 383 // In most socket implementations, closing a socket results in a graceful |
| 380 // connection shutdown, but in Winsock we have to call shutdown explicitly. | 384 // connection shutdown, but in Winsock we have to call shutdown explicitly. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 399 | 403 |
| 400 waiting_read_ = false; | 404 waiting_read_ = false; |
| 401 waiting_write_ = false; | 405 waiting_write_ = false; |
| 402 waiting_connect_ = false; | 406 waiting_connect_ = false; |
| 403 | 407 |
| 404 core_->Detach(); | 408 core_->Detach(); |
| 405 core_ = NULL; | 409 core_ = NULL; |
| 406 } | 410 } |
| 407 | 411 |
| 408 bool TCPClientSocketWin::IsConnected() const { | 412 bool TCPClientSocketWin::IsConnected() const { |
| 413 DCHECK(CalledOnValidThread()); |
| 414 |
| 409 if (socket_ == INVALID_SOCKET || waiting_connect_) | 415 if (socket_ == INVALID_SOCKET || waiting_connect_) |
| 410 return false; | 416 return false; |
| 411 | 417 |
| 412 // Check if connection is alive. | 418 // Check if connection is alive. |
| 413 char c; | 419 char c; |
| 414 int rv = recv(socket_, &c, 1, MSG_PEEK); | 420 int rv = recv(socket_, &c, 1, MSG_PEEK); |
| 415 if (rv == 0) | 421 if (rv == 0) |
| 416 return false; | 422 return false; |
| 417 if (rv == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK) | 423 if (rv == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK) |
| 418 return false; | 424 return false; |
| 419 | 425 |
| 420 return true; | 426 return true; |
| 421 } | 427 } |
| 422 | 428 |
| 423 bool TCPClientSocketWin::IsConnectedAndIdle() const { | 429 bool TCPClientSocketWin::IsConnectedAndIdle() const { |
| 430 DCHECK(CalledOnValidThread()); |
| 431 |
| 424 if (socket_ == INVALID_SOCKET || waiting_connect_) | 432 if (socket_ == INVALID_SOCKET || waiting_connect_) |
| 425 return false; | 433 return false; |
| 426 | 434 |
| 427 // Check if connection is alive and we haven't received any data | 435 // Check if connection is alive and we haven't received any data |
| 428 // unexpectedly. | 436 // unexpectedly. |
| 429 char c; | 437 char c; |
| 430 int rv = recv(socket_, &c, 1, MSG_PEEK); | 438 int rv = recv(socket_, &c, 1, MSG_PEEK); |
| 431 if (rv >= 0) | 439 if (rv >= 0) |
| 432 return false; | 440 return false; |
| 433 if (WSAGetLastError() != WSAEWOULDBLOCK) | 441 if (WSAGetLastError() != WSAEWOULDBLOCK) |
| 434 return false; | 442 return false; |
| 435 | 443 |
| 436 return true; | 444 return true; |
| 437 } | 445 } |
| 438 | 446 |
| 439 int TCPClientSocketWin::GetPeerAddress(AddressList* address) const { | 447 int TCPClientSocketWin::GetPeerAddress(AddressList* address) const { |
| 448 DCHECK(CalledOnValidThread()); |
| 440 DCHECK(address); | 449 DCHECK(address); |
| 441 if (!current_ai_) | 450 if (!current_ai_) |
| 442 return ERR_FAILED; | 451 return ERR_FAILED; |
| 443 address->Copy(current_ai_, false); | 452 address->Copy(current_ai_, false); |
| 444 return OK; | 453 return OK; |
| 445 } | 454 } |
| 446 | 455 |
| 447 int TCPClientSocketWin::Read(IOBuffer* buf, | 456 int TCPClientSocketWin::Read(IOBuffer* buf, |
| 448 int buf_len, | 457 int buf_len, |
| 449 CompletionCallback* callback) { | 458 CompletionCallback* callback) { |
| 459 DCHECK(CalledOnValidThread()); |
| 450 DCHECK_NE(socket_, INVALID_SOCKET); | 460 DCHECK_NE(socket_, INVALID_SOCKET); |
| 451 DCHECK(!waiting_read_); | 461 DCHECK(!waiting_read_); |
| 452 DCHECK(!read_callback_); | 462 DCHECK(!read_callback_); |
| 453 DCHECK(!core_->read_iobuffer_); | 463 DCHECK(!core_->read_iobuffer_); |
| 454 | 464 |
| 455 buf_len = core_->ThrottleReadSize(buf_len); | 465 buf_len = core_->ThrottleReadSize(buf_len); |
| 456 | 466 |
| 457 core_->read_buffer_.len = buf_len; | 467 core_->read_buffer_.len = buf_len; |
| 458 core_->read_buffer_.buf = buf->data(); | 468 core_->read_buffer_.buf = buf->data(); |
| 459 | 469 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 489 core_->WatchForRead(); | 499 core_->WatchForRead(); |
| 490 waiting_read_ = true; | 500 waiting_read_ = true; |
| 491 read_callback_ = callback; | 501 read_callback_ = callback; |
| 492 core_->read_iobuffer_ = buf; | 502 core_->read_iobuffer_ = buf; |
| 493 return ERR_IO_PENDING; | 503 return ERR_IO_PENDING; |
| 494 } | 504 } |
| 495 | 505 |
| 496 int TCPClientSocketWin::Write(IOBuffer* buf, | 506 int TCPClientSocketWin::Write(IOBuffer* buf, |
| 497 int buf_len, | 507 int buf_len, |
| 498 CompletionCallback* callback) { | 508 CompletionCallback* callback) { |
| 509 DCHECK(CalledOnValidThread()); |
| 499 DCHECK_NE(socket_, INVALID_SOCKET); | 510 DCHECK_NE(socket_, INVALID_SOCKET); |
| 500 DCHECK(!waiting_write_); | 511 DCHECK(!waiting_write_); |
| 501 DCHECK(!write_callback_); | 512 DCHECK(!write_callback_); |
| 502 DCHECK_GT(buf_len, 0); | 513 DCHECK_GT(buf_len, 0); |
| 503 DCHECK(!core_->write_iobuffer_); | 514 DCHECK(!core_->write_iobuffer_); |
| 504 | 515 |
| 505 static StatsCounter reads("tcp.writes"); | 516 static StatsCounter reads("tcp.writes"); |
| 506 reads.Increment(); | 517 reads.Increment(); |
| 507 | 518 |
| 508 core_->write_buffer_.len = buf_len; | 519 core_->write_buffer_.len = buf_len; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 539 return MapWinsockError(os_error); | 550 return MapWinsockError(os_error); |
| 540 } | 551 } |
| 541 core_->WatchForWrite(); | 552 core_->WatchForWrite(); |
| 542 waiting_write_ = true; | 553 waiting_write_ = true; |
| 543 write_callback_ = callback; | 554 write_callback_ = callback; |
| 544 core_->write_iobuffer_ = buf; | 555 core_->write_iobuffer_ = buf; |
| 545 return ERR_IO_PENDING; | 556 return ERR_IO_PENDING; |
| 546 } | 557 } |
| 547 | 558 |
| 548 bool TCPClientSocketWin::SetReceiveBufferSize(int32 size) { | 559 bool TCPClientSocketWin::SetReceiveBufferSize(int32 size) { |
| 560 DCHECK(CalledOnValidThread()); |
| 549 int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF, | 561 int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF, |
| 550 reinterpret_cast<const char*>(&size), sizeof(size)); | 562 reinterpret_cast<const char*>(&size), sizeof(size)); |
| 551 DCHECK(!rv) << "Could not set socket receive buffer size: " << GetLastError(); | 563 DCHECK(!rv) << "Could not set socket receive buffer size: " << GetLastError(); |
| 552 return rv == 0; | 564 return rv == 0; |
| 553 } | 565 } |
| 554 | 566 |
| 555 bool TCPClientSocketWin::SetSendBufferSize(int32 size) { | 567 bool TCPClientSocketWin::SetSendBufferSize(int32 size) { |
| 568 DCHECK(CalledOnValidThread()); |
| 556 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, | 569 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, |
| 557 reinterpret_cast<const char*>(&size), sizeof(size)); | 570 reinterpret_cast<const char*>(&size), sizeof(size)); |
| 558 DCHECK(!rv) << "Could not set socket send buffer size: " << GetLastError(); | 571 DCHECK(!rv) << "Could not set socket send buffer size: " << GetLastError(); |
| 559 return rv == 0; | 572 return rv == 0; |
| 560 } | 573 } |
| 561 | 574 |
| 562 int TCPClientSocketWin::CreateSocket(const struct addrinfo* ai) { | 575 int TCPClientSocketWin::CreateSocket(const struct addrinfo* ai) { |
| 563 socket_ = WSASocket(ai->ai_family, ai->ai_socktype, ai->ai_protocol, NULL, 0, | 576 socket_ = WSASocket(ai->ai_family, ai->ai_socktype, ai->ai_protocol, NULL, 0, |
| 564 WSA_FLAG_OVERLAPPED); | 577 WSA_FLAG_OVERLAPPED); |
| 565 if (socket_ == INVALID_SOCKET) { | 578 if (socket_ == INVALID_SOCKET) { |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 724 } else { | 737 } else { |
| 725 net_log_.AddEvent(NetLog::TYPE_SOCKET_BYTES_SENT, | 738 net_log_.AddEvent(NetLog::TYPE_SOCKET_BYTES_SENT, |
| 726 new NetLogIntegerParameter("num_bytes", rv)); | 739 new NetLogIntegerParameter("num_bytes", rv)); |
| 727 } | 740 } |
| 728 } | 741 } |
| 729 core_->write_iobuffer_ = NULL; | 742 core_->write_iobuffer_ = NULL; |
| 730 DoWriteCallback(rv); | 743 DoWriteCallback(rv); |
| 731 } | 744 } |
| 732 | 745 |
| 733 } // namespace net | 746 } // namespace net |
| OLD | NEW |