diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/socket/tcp_client_socket_win.cc | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/net/socket/tcp_client_socket_win.cc b/net/socket/tcp_client_socket_win.cc index a7a8094..600c8ee 100644 --- a/net/socket/tcp_client_socket_win.cc +++ b/net/socket/tcp_client_socket_win.cc @@ -6,6 +6,7 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" +#include "base/field_trial.h" // for SlowStart trial #include "base/memory_debug.h" #include "base/stats_counters.h" #include "base/string_util.h" @@ -119,6 +120,19 @@ class TCPClientSocketWin::Core : public base::RefCounted<Core> { scoped_refptr<IOBuffer> read_iobuffer_; scoped_refptr<IOBuffer> write_iobuffer_; + // Throttle the read size based on our current slow start state. + // Returns the throttled read size. + int ThrottleReadSize(int size) { + if (!use_slow_start_throttle_) + return size; + + if (slow_start_throttle_ < kMaxSlowStartThrottle) { + size = std::min(size, slow_start_throttle_); + slow_start_throttle_ *= 2; + } + return size; + } + private: class ReadDelegate : public base::ObjectWatcher::Delegate { public: @@ -157,16 +171,38 @@ class TCPClientSocketWin::Core : public base::RefCounted<Core> { // |write_watcher_| watches for events from Write(); base::ObjectWatcher write_watcher_; + // When doing reads from the socket, we try to mirror TCP's slow start. + // We do this because otherwise the async IO subsystem artifically delays + // returning data to the application. + static const int kInitialSlowStartThrottle = 1 * 1024; + static const int kMaxSlowStartThrottle = 32 * kInitialSlowStartThrottle; + int slow_start_throttle_; + + static bool use_slow_start_throttle_; + static bool trial_initialized_; + DISALLOW_COPY_AND_ASSIGN(Core); }; +bool TCPClientSocketWin::Core::use_slow_start_throttle_ = false; +bool TCPClientSocketWin::Core::trial_initialized_ = false; + TCPClientSocketWin::Core::Core( TCPClientSocketWin* socket) : socket_(socket), ALLOW_THIS_IN_INITIALIZER_LIST(reader_(this)), - ALLOW_THIS_IN_INITIALIZER_LIST(writer_(this)) { + ALLOW_THIS_IN_INITIALIZER_LIST(writer_(this)), + slow_start_throttle_(kInitialSlowStartThrottle) { memset(&read_overlapped_, 0, sizeof(read_overlapped_)); memset(&write_overlapped_, 0, sizeof(write_overlapped_)); + + // Initialize the AsyncSlowStart FieldTrial. + if (!trial_initialized_) { + trial_initialized_ = true; + FieldTrial* trial = FieldTrialList::Find("AsyncSlowStart"); + if (trial && trial->group_name() == "_AsyncSlowStart") + use_slow_start_throttle_ = true; + } } TCPClientSocketWin::Core::~Core() { @@ -370,6 +406,8 @@ int TCPClientSocketWin::Read(IOBuffer* buf, DCHECK(!read_callback_); DCHECK(!core_->read_iobuffer_); + buf_len = core_->ThrottleReadSize(buf_len); + core_->read_buffer_.len = buf_len; core_->read_buffer_.buf = buf->data(); |