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

Side by Side Diff: net/tools/flip_server/flip_in_mem_edsm_server.cc

Issue 6327022: Optimizations to fill packets better for the edsm server.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 10 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 | « no previous file | 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) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 <dirent.h> 5 #include <dirent.h>
6 #include <netinet/tcp.h> // For TCP_NODELAY 6 #include <netinet/tcp.h> // For TCP_NODELAY
7 #include <sys/socket.h> 7 #include <sys/socket.h>
8 #include <sys/types.h> 8 #include <sys/types.h>
9 #include <sys/file.h> 9 #include <sys/file.h>
10 #include <sys/stat.h> 10 #include <sys/stat.h>
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 PrintSslError(); 272 PrintSslError();
273 273
274 SSL_set_accept_state(ssl); 274 SSL_set_accept_state(ssl);
275 PrintSslError(); 275 PrintSslError();
276 276
277 return ssl; 277 return ssl;
278 } 278 }
279 279
280 //////////////////////////////////////////////////////////////////////////////// 280 ////////////////////////////////////////////////////////////////////////////////
281 281
282 const int kMSS = 1400; // Linux default 282 const int kMSS = 1460;
283 const int kSSLOverhead = 33; 283 const int kSSLOverhead = 25;
284 const int kSpdyOverhead = SpdyFrame::size(); 284 const int kSpdyOverhead = SpdyFrame::size();
285 const int kInitialDataSendersThreshold = (2 * kMSS) - kSpdyOverhead; 285 const int kInitialDataSendersThreshold = (2 * kMSS) - kSpdyOverhead;
286 const int kSSLSegmentSize = (1 * kMSS) - kSSLOverhead; 286 const int kSSLSegmentSize = (1 * kMSS) - kSSLOverhead;
287 const int kSpdySegmentSize = kSSLSegmentSize - kSpdyOverhead; 287 const int kSpdySegmentSize = kSSLSegmentSize - kSpdyOverhead;
288 288
289 //////////////////////////////////////////////////////////////////////////////// 289 ////////////////////////////////////////////////////////////////////////////////
290 290
291 class DataFrame { 291 class DataFrame {
292 public: 292 public:
293 const char* data; 293 const char* data;
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after
802 events_(0), 802 events_(0),
803 registered_in_epoll_server_(false), 803 registered_in_epoll_server_(false),
804 initialized_(false), 804 initialized_(false),
805 protocol_detected_(false), 805 protocol_detected_(false),
806 connection_complete_(false), 806 connection_complete_(false),
807 connection_pool_(NULL), 807 connection_pool_(NULL),
808 epoll_server_(epoll_server), 808 epoll_server_(epoll_server),
809 ssl_state_(ssl_state), 809 ssl_state_(ssl_state),
810 memory_cache_(memory_cache), 810 memory_cache_(memory_cache),
811 acceptor_(acceptor), 811 acceptor_(acceptor),
812 read_buffer_(4096*10), 812 read_buffer_(kSpdySegmentSize * 40),
813 sm_spdy_interface_(NULL), 813 sm_spdy_interface_(NULL),
814 sm_http_interface_(NULL), 814 sm_http_interface_(NULL),
815 sm_streamer_interface_(NULL), 815 sm_streamer_interface_(NULL),
816 sm_interface_(NULL), 816 sm_interface_(NULL),
817 log_prefix_(log_prefix), 817 log_prefix_(log_prefix),
818 max_bytes_sent_per_dowrite_(4096), 818 max_bytes_sent_per_dowrite_(4096),
819 ssl_(NULL), 819 ssl_(NULL),
820 last_read_time_(0) 820 last_read_time_(0)
821 {} 821 {}
822 822
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
966 966
967 epoll_server_->RegisterFD(fd_, this, EPOLLIN | EPOLLOUT | EPOLLET); 967 epoll_server_->RegisterFD(fd_, this, EPOLLIN | EPOLLOUT | EPOLLET);
968 968
969 if (use_ssl) { 969 if (use_ssl) {
970 ssl_ = spdy_new_ssl(ssl_state_->ssl_ctx); 970 ssl_ = spdy_new_ssl(ssl_state_->ssl_ctx);
971 SSL_set_fd(ssl_, fd_); 971 SSL_set_fd(ssl_, fd_);
972 PrintSslError(); 972 PrintSslError();
973 } 973 }
974 } 974 }
975 975
976 void CorkSocket() {
977 int state = 1;
978 int rv = setsockopt(fd_, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
979 if (rv < 0)
980 VLOG(1) << "setsockopt(CORK): " << errno;
981 }
982
983 void UncorkSocket() {
984 int state = 0;
985 int rv = setsockopt(fd_, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
986 if (rv < 0)
987 VLOG(1) << "setsockopt(CORK): " << errno;
988 }
989
976 int Send(const char* data, int len, int flags) { 990 int Send(const char* data, int len, int flags) {
977 ssize_t bytes_written = 0; 991 int rv;
992 CorkSocket();
fenix 2011/01/27 20:34:59 hopefully no ill effects to corking when it is alr
978 if (ssl_) { 993 if (ssl_) {
994 ssize_t bytes_written = 0;
979 // Write smallish chunks to SSL so that we don't have large 995 // Write smallish chunks to SSL so that we don't have large
980 // multi-packet TLS records to receive before being able to handle 996 // multi-packet TLS records to receive before being able to handle
981 // the data. 997 // the data. We don't have to be too careful here, because our data
998 // frames are already getting chunked appropriately, and those are
999 // the most likely "big" frames.
982 while(len > 0) { 1000 while(len > 0) {
983 const int kMaxTLSRecordSize = 1460; 1001 const int kMaxTLSRecordSize = 1500;
984 const char* ptr = &(data[bytes_written]); 1002 const char* ptr = &(data[bytes_written]);
985 int chunksize = std::min(len, kMaxTLSRecordSize); 1003 int chunksize = std::min(len, kMaxTLSRecordSize);
986 int rv = SSL_write(ssl_, ptr, chunksize); 1004 rv = SSL_write(ssl_, ptr, chunksize);
1005 VLOG(2) << "SSLWrite(" << chunksize << " bytes): " << rv;
987 if (rv <= 0) { 1006 if (rv <= 0) {
988 switch(SSL_get_error(ssl_, rv)) { 1007 switch(SSL_get_error(ssl_, rv)) {
989 case SSL_ERROR_WANT_READ: 1008 case SSL_ERROR_WANT_READ:
990 case SSL_ERROR_WANT_WRITE: 1009 case SSL_ERROR_WANT_WRITE:
991 case SSL_ERROR_WANT_ACCEPT: 1010 case SSL_ERROR_WANT_ACCEPT:
992 case SSL_ERROR_WANT_CONNECT: 1011 case SSL_ERROR_WANT_CONNECT:
993 rv = -2; 1012 rv = -2;
994 break; 1013 break;
995 default: 1014 default:
996 PrintSslError(); 1015 PrintSslError();
997 break; 1016 break;
998 } 1017 }
999 // If we wrote some data, return that count. Otherwise 1018 break;
1000 // return the stall error.
1001 return bytes_written > 0 ? bytes_written : rv;
1002 } 1019 }
1003 bytes_written += rv; 1020 bytes_written += rv;
1004 len -= rv; 1021 len -= rv;
1005 if (rv != chunksize) 1022 if (rv != chunksize)
1006 break; // If we couldn't write everything, we're implicitly stalled 1023 break; // If we couldn't write everything, we're implicitly stalled
1007 } 1024 }
1008 if (!(flags & MSG_MORE)) { 1025 // If we wrote some data, return that count. Otherwise
1009 int state = 0; 1026 // return the stall error.
1010 setsockopt( fd_, IPPROTO_TCP, TCP_CORK, &state, sizeof( state ) ); 1027 if (bytes_written > 0)
1011 state = 1; 1028 rv = bytes_written;
1012 setsockopt( fd_, IPPROTO_TCP, TCP_CORK, &state, sizeof( state ) );
1013 }
1014 } else { 1029 } else {
1015 bytes_written = send(fd_, data, len, flags); 1030 rv = send(fd_, data, len, flags);
1016 } 1031 }
1017 return bytes_written; 1032 if (!(flags & MSG_MORE))
1033 UncorkSocket();
1034 return rv;
1018 } 1035 }
1019 1036
1020 // the following are from the EpollCallbackInterface 1037 // the following are from the EpollCallbackInterface
1021 virtual void OnRegistration(EpollServer* eps, int fd, int event_mask) { 1038 virtual void OnRegistration(EpollServer* eps, int fd, int event_mask) {
1022 registered_in_epoll_server_ = true; 1039 registered_in_epoll_server_ = true;
1023 } 1040 }
1024 virtual void OnModification(int fd, int event_mask) { } 1041 virtual void OnModification(int fd, int event_mask) { }
1025 virtual void OnEvent(int fd, EpollEvent* event) { 1042 virtual void OnEvent(int fd, EpollEvent* event) {
1026 events_ |= event->in_events; 1043 events_ |= event->in_events;
1027 HandleEvents(); 1044 HandleEvents();
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
1177 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT 1194 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT
1178 << (sm_spdy_interface_ ? "Creating" : "Reusing") 1195 << (sm_spdy_interface_ ? "Creating" : "Reusing")
1179 << " SPDY interface."; 1196 << " SPDY interface.";
1180 if (!sm_spdy_interface_) 1197 if (!sm_spdy_interface_)
1181 sm_spdy_interface_ = NewSpdySM(this, NULL, epoll_server_, 1198 sm_spdy_interface_ = NewSpdySM(this, NULL, epoll_server_,
1182 memory_cache_, acceptor_); 1199 memory_cache_, acceptor_);
1183 sm_interface_ = sm_spdy_interface_; 1200 sm_interface_ = sm_spdy_interface_;
1184 } 1201 }
1185 break; 1202 break;
1186 } 1203 }
1204
1205 CorkSocket();
1187 if (!sm_interface_->PostAcceptHook()) 1206 if (!sm_interface_->PostAcceptHook())
1188 return false; 1207 return false;
1189 1208
1190 return true; 1209 return true;
1191 } 1210 }
1192 1211
1193 bool DoRead() { 1212 bool DoRead() {
1194 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "DoRead()"; 1213 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "DoRead()";
1195 while (!read_buffer_.Full()) { 1214 while (!read_buffer_.Full()) {
1196 char* bytes; 1215 char* bytes;
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
1347 if (sm_interface_ && output_list_.size() < 2) { 1366 if (sm_interface_ && output_list_.size() < 2) {
1348 sm_interface_->GetOutput(); 1367 sm_interface_->GetOutput();
1349 } 1368 }
1350 DataFrame* data_frame = output_list_.front(); 1369 DataFrame* data_frame = output_list_.front();
1351 const char* bytes = data_frame->data; 1370 const char* bytes = data_frame->data;
1352 int size = data_frame->size; 1371 int size = data_frame->size;
1353 bytes += data_frame->index; 1372 bytes += data_frame->index;
1354 size -= data_frame->index; 1373 size -= data_frame->index;
1355 DCHECK_GE(size, 0); 1374 DCHECK_GE(size, 0);
1356 if (size <= 0) { 1375 if (size <= 0) {
1357 // Empty data frame. Indicates end of data from client.
1358 // Uncork the socket.
1359 int state = 0;
1360 VLOG(2) << log_prefix_ << "Empty data frame, uncorking socket.";
1361 setsockopt( fd_, IPPROTO_TCP, TCP_CORK, &state, sizeof( state ) );
1362 output_list_.pop_front(); 1376 output_list_.pop_front();
1363 delete data_frame; 1377 delete data_frame;
1364 continue; 1378 continue;
1365 } 1379 }
1366 1380
1367 flags = MSG_NOSIGNAL | MSG_DONTWAIT; 1381 flags = MSG_NOSIGNAL | MSG_DONTWAIT;
1382 // Look for a queue size > 1 because |this| frame is remains on the list
1383 // until it has finished sending.
1368 if (output_list_.size() > 1) { 1384 if (output_list_.size() > 1) {
1369 VLOG(2) << log_prefix_ << "Outlist size: " << output_list_.size() 1385 VLOG(2) << log_prefix_ << "Outlist size: " << output_list_.size()
1370 << ": Adding MSG_MORE flag"; 1386 << ": Adding MSG_MORE flag";
1371 flags |= MSG_MORE; 1387 flags |= MSG_MORE;
1372 } 1388 }
1373 VLOG(2) << log_prefix_ << "Attempting to send " << size << " bytes."; 1389 VLOG(2) << log_prefix_ << "Attempting to send " << size << " bytes.";
1374 ssize_t bytes_written = Send(bytes, size, flags); 1390 ssize_t bytes_written = Send(bytes, size, flags);
1375 int stored_errno = errno; 1391 int stored_errno = errno;
1376 if (bytes_written == -1) { 1392 if (bytes_written == -1) {
1377 switch (stored_errno) { 1393 switch (stored_errno) {
(...skipping 21 matching lines...) Expand all
1399 } else if (bytes_written == -2) { 1415 } else if (bytes_written == -2) {
1400 // -2 handles SSL_ERROR_WANT_* errors 1416 // -2 handles SSL_ERROR_WANT_* errors
1401 events_ &= ~EPOLLOUT; 1417 events_ &= ~EPOLLOUT;
1402 goto done; 1418 goto done;
1403 } 1419 }
1404 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT 1420 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT
1405 << "0 bytes written with send call."; 1421 << "0 bytes written with send call.";
1406 goto error_or_close; 1422 goto error_or_close;
1407 } 1423 }
1408 done: 1424 done:
1425 UncorkSocket();
1409 return true; 1426 return true;
1410 1427
1411 error_or_close: 1428 error_or_close:
1412 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT 1429 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT
1413 << "DoWrite: error_or_close. Returning false " 1430 << "DoWrite: error_or_close. Returning false "
1414 << "after cleaning up"; 1431 << "after cleaning up";
1415 Cleanup("DoWrite"); 1432 Cleanup("DoWrite");
1433 UncorkSocket();
1416 return false; 1434 return false;
1417 } 1435 }
1418 1436
1419 friend ostream& operator<<(ostream& os, const SMConnection& c) { 1437 friend ostream& operator<<(ostream& os, const SMConnection& c) {
1420 os << &c << "\n"; 1438 os << &c << "\n";
1421 return os; 1439 return os;
1422 } 1440 }
1423 1441
1424 void Reset() { 1442 void Reset() {
1425 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "Resetting"; 1443 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "Resetting";
(...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after
1941 1959
1942 // SMInterface's Cleanup is currently only called by SMConnection after a 1960 // SMInterface's Cleanup is currently only called by SMConnection after a
1943 // protocol message as been fully read. Spdy's SMInterface does not need 1961 // protocol message as been fully read. Spdy's SMInterface does not need
1944 // to do any cleanup at this time. 1962 // to do any cleanup at this time.
1945 // TODO (klindsay) This method is probably not being used properly and 1963 // TODO (klindsay) This method is probably not being used properly and
1946 // some logic review and method renaming is probably in order. 1964 // some logic review and method renaming is probably in order.
1947 void Cleanup() {} 1965 void Cleanup() {}
1948 1966
1949 // Send a settings frame 1967 // Send a settings frame
1950 int PostAcceptHook() { 1968 int PostAcceptHook() {
1951 ssize_t bytes_written;
1952 spdy::SpdySettings settings; 1969 spdy::SpdySettings settings;
1953 spdy::SettingsFlagsAndId settings_id(0); 1970 spdy::SettingsFlagsAndId settings_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS);
1954 settings_id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS);
1955 settings.push_back(spdy::SpdySetting(settings_id, 100)); 1971 settings.push_back(spdy::SpdySetting(settings_id, 100));
1956 scoped_ptr<SpdySettingsControlFrame> 1972 SpdySettingsControlFrame* settings_frame =
1957 settings_frame(spdy_framer_->CreateSettings(settings)); 1973 spdy_framer_->CreateSettings(settings);
1958 1974
1959 char* bytes = settings_frame->data();
1960 size_t size = SpdyFrame::size() + settings_frame->length();
1961 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Sending Settings Frame"; 1975 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Sending Settings Frame";
1962 bytes_written = connection_->Send(bytes, size, 1976 SpdyFrameDataFrame* df = new SpdyFrameDataFrame;
1963 MSG_NOSIGNAL | MSG_DONTWAIT); 1977 df->size = settings_frame->length() + SpdyFrame::size();
1964 if (static_cast<size_t>(bytes_written) != size) { 1978 df->data = settings_frame->data();
1965 LOG(ERROR) << "Trouble sending SETTINGS frame! (" << errno << ")"; 1979 df->frame = settings_frame;
1966 if (errno == EAGAIN) { 1980 df->delete_when_done = true;
1967 return 0; 1981 EnqueueDataFrame(df);
1968 }
1969 }
1970 return 1; 1982 return 1;
1971 } 1983 }
1972 1984
1973 void AddAssociatedContent(FileData* file_data) { 1985 void AddAssociatedContent(FileData* file_data) {
1974 for (unsigned int i = 0; i < file_data->related_files.size(); ++i) { 1986 for (unsigned int i = 0; i < file_data->related_files.size(); ++i) {
1975 pair<int, string>& related_file = file_data->related_files[i]; 1987 pair<int, string>& related_file = file_data->related_files[i];
1976 MemCacheIter mci; 1988 MemCacheIter mci;
1977 string filename = "GET_"; 1989 string filename = "GET_";
1978 filename += related_file.second; 1990 filename += related_file.second;
1979 if (!memory_cache_->AssignFileData(filename, &mci)) { 1991 if (!memory_cache_->AssignFileData(filename, &mci)) {
(...skipping 1427 matching lines...) Expand 10 before | Expand all | Expand 10 after
3407 } 3419 }
3408 break; 3420 break;
3409 } 3421 }
3410 usleep(1000*10); // 10 ms 3422 usleep(1000*10); // 10 ms
3411 } 3423 }
3412 3424
3413 unlink(PIDFILE); 3425 unlink(PIDFILE);
3414 close(pidfile_fd); 3426 close(pidfile_fd);
3415 return 0; 3427 return 0;
3416 } 3428 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698