Chromium Code Reviews| Index: net/tools/flip_server/flip_in_mem_edsm_server.cc |
| =================================================================== |
| --- net/tools/flip_server/flip_in_mem_edsm_server.cc (revision 72536) |
| +++ net/tools/flip_server/flip_in_mem_edsm_server.cc (working copy) |
| @@ -279,8 +279,8 @@ |
| //////////////////////////////////////////////////////////////////////////////// |
| -const int kMSS = 1400; // Linux default |
| -const int kSSLOverhead = 33; |
| +const int kMSS = 1460; |
| +const int kSSLOverhead = 25; |
| const int kSpdyOverhead = SpdyFrame::size(); |
| const int kInitialDataSendersThreshold = (2 * kMSS) - kSpdyOverhead; |
| const int kSSLSegmentSize = (1 * kMSS) - kSSLOverhead; |
| @@ -809,7 +809,7 @@ |
| ssl_state_(ssl_state), |
| memory_cache_(memory_cache), |
| acceptor_(acceptor), |
| - read_buffer_(4096*10), |
| + read_buffer_(kSpdySegmentSize * 40), |
| sm_spdy_interface_(NULL), |
| sm_http_interface_(NULL), |
| sm_streamer_interface_(NULL), |
| @@ -973,17 +973,36 @@ |
| } |
| } |
| + void CorkSocket() { |
| + int state = 1; |
| + int rv = setsockopt(fd_, IPPROTO_TCP, TCP_CORK, &state, sizeof(state)); |
| + if (rv < 0) |
| + VLOG(1) << "setsockopt(CORK): " << errno; |
| + } |
| + |
| + void UncorkSocket() { |
| + int state = 0; |
| + int rv = setsockopt(fd_, IPPROTO_TCP, TCP_CORK, &state, sizeof(state)); |
| + if (rv < 0) |
| + VLOG(1) << "setsockopt(CORK): " << errno; |
| + } |
| + |
| int Send(const char* data, int len, int flags) { |
| - ssize_t bytes_written = 0; |
| + int rv; |
| + CorkSocket(); |
|
fenix
2011/01/27 20:34:59
hopefully no ill effects to corking when it is alr
|
| if (ssl_) { |
| + ssize_t bytes_written = 0; |
| // Write smallish chunks to SSL so that we don't have large |
| // multi-packet TLS records to receive before being able to handle |
| - // the data. |
| + // the data. We don't have to be too careful here, because our data |
| + // frames are already getting chunked appropriately, and those are |
| + // the most likely "big" frames. |
| while(len > 0) { |
| - const int kMaxTLSRecordSize = 1460; |
| + const int kMaxTLSRecordSize = 1500; |
| const char* ptr = &(data[bytes_written]); |
| int chunksize = std::min(len, kMaxTLSRecordSize); |
| - int rv = SSL_write(ssl_, ptr, chunksize); |
| + rv = SSL_write(ssl_, ptr, chunksize); |
| + VLOG(2) << "SSLWrite(" << chunksize << " bytes): " << rv; |
| if (rv <= 0) { |
| switch(SSL_get_error(ssl_, rv)) { |
| case SSL_ERROR_WANT_READ: |
| @@ -996,25 +1015,23 @@ |
| PrintSslError(); |
| break; |
| } |
| - // If we wrote some data, return that count. Otherwise |
| - // return the stall error. |
| - return bytes_written > 0 ? bytes_written : rv; |
| + break; |
| } |
| bytes_written += rv; |
| len -= rv; |
| if (rv != chunksize) |
| break; // If we couldn't write everything, we're implicitly stalled |
| } |
| - if (!(flags & MSG_MORE)) { |
| - int state = 0; |
| - setsockopt( fd_, IPPROTO_TCP, TCP_CORK, &state, sizeof( state ) ); |
| - state = 1; |
| - setsockopt( fd_, IPPROTO_TCP, TCP_CORK, &state, sizeof( state ) ); |
| - } |
| + // If we wrote some data, return that count. Otherwise |
| + // return the stall error. |
| + if (bytes_written > 0) |
| + rv = bytes_written; |
| } else { |
| - bytes_written = send(fd_, data, len, flags); |
| + rv = send(fd_, data, len, flags); |
| } |
| - return bytes_written; |
| + if (!(flags & MSG_MORE)) |
| + UncorkSocket(); |
| + return rv; |
| } |
| // the following are from the EpollCallbackInterface |
| @@ -1184,6 +1201,8 @@ |
| } |
| break; |
| } |
| + |
| + CorkSocket(); |
| if (!sm_interface_->PostAcceptHook()) |
| return false; |
| @@ -1354,17 +1373,14 @@ |
| size -= data_frame->index; |
| DCHECK_GE(size, 0); |
| if (size <= 0) { |
| - // Empty data frame. Indicates end of data from client. |
| - // Uncork the socket. |
| - int state = 0; |
| - VLOG(2) << log_prefix_ << "Empty data frame, uncorking socket."; |
| - setsockopt( fd_, IPPROTO_TCP, TCP_CORK, &state, sizeof( state ) ); |
| output_list_.pop_front(); |
| delete data_frame; |
| continue; |
| } |
| flags = MSG_NOSIGNAL | MSG_DONTWAIT; |
| + // Look for a queue size > 1 because |this| frame is remains on the list |
| + // until it has finished sending. |
| if (output_list_.size() > 1) { |
| VLOG(2) << log_prefix_ << "Outlist size: " << output_list_.size() |
| << ": Adding MSG_MORE flag"; |
| @@ -1406,6 +1422,7 @@ |
| goto error_or_close; |
| } |
| done: |
| + UncorkSocket(); |
| return true; |
| error_or_close: |
| @@ -1413,6 +1430,7 @@ |
| << "DoWrite: error_or_close. Returning false " |
| << "after cleaning up"; |
| Cleanup("DoWrite"); |
| + UncorkSocket(); |
| return false; |
| } |
| @@ -1948,25 +1966,19 @@ |
| // Send a settings frame |
| int PostAcceptHook() { |
| - ssize_t bytes_written; |
| spdy::SpdySettings settings; |
| - spdy::SettingsFlagsAndId settings_id(0); |
| - settings_id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS); |
| + spdy::SettingsFlagsAndId settings_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS); |
| settings.push_back(spdy::SpdySetting(settings_id, 100)); |
| - scoped_ptr<SpdySettingsControlFrame> |
| - settings_frame(spdy_framer_->CreateSettings(settings)); |
| + SpdySettingsControlFrame* settings_frame = |
| + spdy_framer_->CreateSettings(settings); |
| - char* bytes = settings_frame->data(); |
| - size_t size = SpdyFrame::size() + settings_frame->length(); |
| VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Sending Settings Frame"; |
| - bytes_written = connection_->Send(bytes, size, |
| - MSG_NOSIGNAL | MSG_DONTWAIT); |
| - if (static_cast<size_t>(bytes_written) != size) { |
| - LOG(ERROR) << "Trouble sending SETTINGS frame! (" << errno << ")"; |
| - if (errno == EAGAIN) { |
| - return 0; |
| - } |
| - } |
| + SpdyFrameDataFrame* df = new SpdyFrameDataFrame; |
| + df->size = settings_frame->length() + SpdyFrame::size(); |
| + df->data = settings_frame->data(); |
| + df->frame = settings_frame; |
| + df->delete_when_done = true; |
| + EnqueueDataFrame(df); |
| return 1; |
| } |