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 |