Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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/field_trial.h" // for SlowStart trial | |
| 9 #include "base/memory_debug.h" | 10 #include "base/memory_debug.h" |
| 10 #include "base/string_util.h" | 11 #include "base/string_util.h" |
| 11 #include "base/sys_info.h" | 12 #include "base/sys_info.h" |
| 12 #include "base/trace_event.h" | 13 #include "base/trace_event.h" |
| 13 #include "net/base/io_buffer.h" | 14 #include "net/base/io_buffer.h" |
| 14 #include "net/base/net_errors.h" | 15 #include "net/base/net_errors.h" |
| 15 #include "net/base/winsock_init.h" | 16 #include "net/base/winsock_init.h" |
| 16 | 17 |
| 17 namespace net { | 18 namespace net { |
| 18 | 19 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 111 // |write_overlapped_| is only used for Write(); | 112 // |write_overlapped_| is only used for Write(); |
| 112 OVERLAPPED read_overlapped_; | 113 OVERLAPPED read_overlapped_; |
| 113 OVERLAPPED write_overlapped_; | 114 OVERLAPPED write_overlapped_; |
| 114 | 115 |
| 115 // The buffers used in Read() and Write(). | 116 // The buffers used in Read() and Write(). |
| 116 WSABUF read_buffer_; | 117 WSABUF read_buffer_; |
| 117 WSABUF write_buffer_; | 118 WSABUF write_buffer_; |
| 118 scoped_refptr<IOBuffer> read_iobuffer_; | 119 scoped_refptr<IOBuffer> read_iobuffer_; |
| 119 scoped_refptr<IOBuffer> write_iobuffer_; | 120 scoped_refptr<IOBuffer> write_iobuffer_; |
| 120 | 121 |
| 122 // Throttle the read size based on our current slow start state. | |
| 123 // Returns the throttled read size. | |
| 124 int ThrottleReadSize(int size) { | |
|
wtc
2009/08/25 23:58:16
This method and the related data members should be
| |
| 125 if (!use_slow_start_throttle_) | |
| 126 return size; | |
| 127 | |
| 128 if (slow_start_throttle_ < kMaxSlowStartThrottle) { | |
| 129 size = std::min(size, slow_start_throttle_); | |
| 130 slow_start_throttle_ *= 2; | |
| 131 } | |
| 132 return size; | |
| 133 } | |
| 134 | |
| 121 private: | 135 private: |
| 122 class ReadDelegate : public base::ObjectWatcher::Delegate { | 136 class ReadDelegate : public base::ObjectWatcher::Delegate { |
| 123 public: | 137 public: |
| 124 explicit ReadDelegate(Core* core) : core_(core) {} | 138 explicit ReadDelegate(Core* core) : core_(core) {} |
| 125 virtual ~ReadDelegate() {} | 139 virtual ~ReadDelegate() {} |
| 126 | 140 |
| 127 // base::ObjectWatcher::Delegate methods: | 141 // base::ObjectWatcher::Delegate methods: |
| 128 virtual void OnObjectSignaled(HANDLE object); | 142 virtual void OnObjectSignaled(HANDLE object); |
| 129 | 143 |
| 130 private: | 144 private: |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 149 // |reader_| handles the signals from |read_watcher_|. | 163 // |reader_| handles the signals from |read_watcher_|. |
| 150 ReadDelegate reader_; | 164 ReadDelegate reader_; |
| 151 // |writer_| handles the signals from |write_watcher_|. | 165 // |writer_| handles the signals from |write_watcher_|. |
| 152 WriteDelegate writer_; | 166 WriteDelegate writer_; |
| 153 | 167 |
| 154 // |read_watcher_| watches for events from Connect() and Read(). | 168 // |read_watcher_| watches for events from Connect() and Read(). |
| 155 base::ObjectWatcher read_watcher_; | 169 base::ObjectWatcher read_watcher_; |
| 156 // |write_watcher_| watches for events from Write(); | 170 // |write_watcher_| watches for events from Write(); |
| 157 base::ObjectWatcher write_watcher_; | 171 base::ObjectWatcher write_watcher_; |
| 158 | 172 |
| 173 // When doing reads from the socket, we try to mirror TCP's slow start. | |
| 174 // We do this because otherwise the async IO subsystem artifically delays | |
| 175 // returning data to the application. | |
| 176 static const int kInitialSlowStartThrottle = 1 * 1024; | |
| 177 static const int kMaxSlowStartThrottle = 32 * kInitialSlowStartThrottle; | |
| 178 int slow_start_throttle_; | |
| 179 | |
| 180 static bool use_slow_start_throttle_; | |
| 181 static bool trial_initialized_; | |
| 182 | |
| 159 DISALLOW_COPY_AND_ASSIGN(Core); | 183 DISALLOW_COPY_AND_ASSIGN(Core); |
| 160 }; | 184 }; |
| 161 | 185 |
| 186 bool TCPClientSocketWin::Core::use_slow_start_throttle_ = true; | |
| 187 bool TCPClientSocketWin::Core::trial_initialized_ = false; | |
| 188 | |
| 162 TCPClientSocketWin::Core::Core( | 189 TCPClientSocketWin::Core::Core( |
| 163 TCPClientSocketWin* socket) | 190 TCPClientSocketWin* socket) |
| 164 : socket_(socket), | 191 : socket_(socket), |
| 165 ALLOW_THIS_IN_INITIALIZER_LIST(reader_(this)), | 192 ALLOW_THIS_IN_INITIALIZER_LIST(reader_(this)), |
| 166 ALLOW_THIS_IN_INITIALIZER_LIST(writer_(this)) { | 193 ALLOW_THIS_IN_INITIALIZER_LIST(writer_(this)), |
| 194 slow_start_throttle_(kInitialSlowStartThrottle) { | |
| 167 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); | 195 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); |
| 168 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); | 196 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); |
| 197 | |
| 198 // Initialize the AsyncSlowStart FieldTrial. | |
| 199 if (!trial_initialized_) { | |
| 200 trial_initialized_ = true; | |
| 201 scoped_refptr<FieldTrial> trial = new FieldTrial("AsyncSlowStart", 100); | |
| 202 int my_group = trial->AppendGroup("_AsyncSlowStart", 50); | |
| 203 trial->AppendGroup("_AsyncSlowStart_off", 50); | |
| 204 | |
| 205 // Only use the throttling if the FieldTrial is enabled. | |
| 206 use_slow_start_throttle_ = trial->group() == my_group; | |
| 207 } | |
| 169 } | 208 } |
| 170 | 209 |
| 171 TCPClientSocketWin::Core::~Core() { | 210 TCPClientSocketWin::Core::~Core() { |
| 172 // Make sure the message loop is not watching this object anymore. | 211 // Make sure the message loop is not watching this object anymore. |
| 173 read_watcher_.StopWatching(); | 212 read_watcher_.StopWatching(); |
| 174 write_watcher_.StopWatching(); | 213 write_watcher_.StopWatching(); |
| 175 | 214 |
| 176 WSACloseEvent(read_overlapped_.hEvent); | 215 WSACloseEvent(read_overlapped_.hEvent); |
| 177 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); | 216 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); |
| 178 WSACloseEvent(write_overlapped_.hEvent); | 217 WSACloseEvent(write_overlapped_.hEvent); |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 359 } | 398 } |
| 360 | 399 |
| 361 int TCPClientSocketWin::Read(IOBuffer* buf, | 400 int TCPClientSocketWin::Read(IOBuffer* buf, |
| 362 int buf_len, | 401 int buf_len, |
| 363 CompletionCallback* callback) { | 402 CompletionCallback* callback) { |
| 364 DCHECK_NE(socket_, INVALID_SOCKET); | 403 DCHECK_NE(socket_, INVALID_SOCKET); |
| 365 DCHECK(!waiting_read_); | 404 DCHECK(!waiting_read_); |
| 366 DCHECK(!read_callback_); | 405 DCHECK(!read_callback_); |
| 367 DCHECK(!core_->read_iobuffer_); | 406 DCHECK(!core_->read_iobuffer_); |
| 368 | 407 |
| 408 buf_len = core_->ThrottleReadSize(buf_len); | |
| 409 | |
| 369 core_->read_buffer_.len = buf_len; | 410 core_->read_buffer_.len = buf_len; |
| 370 core_->read_buffer_.buf = buf->data(); | 411 core_->read_buffer_.buf = buf->data(); |
| 371 | 412 |
| 372 TRACE_EVENT_BEGIN("socket.read", this, ""); | 413 TRACE_EVENT_BEGIN("socket.read", this, ""); |
| 373 // TODO(wtc): Remove the CHECK after enough testing. | 414 // TODO(wtc): Remove the CHECK after enough testing. |
| 374 CHECK(WaitForSingleObject(core_->read_overlapped_.hEvent, 0) == WAIT_TIMEOUT); | 415 CHECK(WaitForSingleObject(core_->read_overlapped_.hEvent, 0) == WAIT_TIMEOUT); |
| 375 DWORD num, flags = 0; | 416 DWORD num, flags = 0; |
| 376 int rv = WSARecv(socket_, &core_->read_buffer_, 1, &num, &flags, | 417 int rv = WSARecv(socket_, &core_->read_buffer_, 1, &num, &flags, |
| 377 &core_->read_overlapped_, NULL); | 418 &core_->read_overlapped_, NULL); |
| 378 if (rv == 0) { | 419 if (rv == 0) { |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 578 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, | 619 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, |
| 579 &num_bytes, FALSE, &flags); | 620 &num_bytes, FALSE, &flags); |
| 580 WSAResetEvent(core_->write_overlapped_.hEvent); | 621 WSAResetEvent(core_->write_overlapped_.hEvent); |
| 581 TRACE_EVENT_END("socket.write", this, StringPrintf("%d bytes", num_bytes)); | 622 TRACE_EVENT_END("socket.write", this, StringPrintf("%d bytes", num_bytes)); |
| 582 waiting_write_ = false; | 623 waiting_write_ = false; |
| 583 core_->write_iobuffer_ = NULL; | 624 core_->write_iobuffer_ = NULL; |
| 584 DoWriteCallback(ok ? num_bytes : MapWinsockError(WSAGetLastError())); | 625 DoWriteCallback(ok ? num_bytes : MapWinsockError(WSAGetLastError())); |
| 585 } | 626 } |
| 586 | 627 |
| 587 } // namespace net | 628 } // namespace net |
| OLD | NEW |