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

Side by Side Diff: net/socket/tcp_client_socket_win.cc

Issue 173259: Implement a read-size throttle within the TCP socket. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 3 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 | « chrome/renderer/render_view.cc ('k') | no next file » | 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) 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
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
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
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
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
OLDNEW
« no previous file with comments | « chrome/renderer/render_view.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698