Changeset 1754
- Timestamp:
- 08/06/08 18:58:18 (5 months ago)
- Files:
-
- cherokee/trunk/ChangeLog (modified) (1 diff)
- cherokee/trunk/cherokee/common-internal.h (modified) (1 diff)
- cherokee/trunk/cherokee/connection.c (modified) (1 diff)
- cherokee/trunk/cherokee/downloader_async.c (modified) (1 diff)
- cherokee/trunk/cherokee/fcgi_manager.c (modified) (1 diff)
- cherokee/trunk/cherokee/handler_file.c (modified) (2 diffs)
- cherokee/trunk/cherokee/handler_scgi.c (modified) (1 diff)
- cherokee/trunk/cherokee/logger_writer.c (modified) (2 diffs)
- cherokee/trunk/cherokee/server.c (modified) (5 diffs)
- cherokee/trunk/cherokee/socket.c (modified) (3 diffs)
- cherokee/trunk/cherokee/source.c (modified) (2 diffs)
- cherokee/trunk/cherokee/thread.c (modified) (5 diffs)
- cherokee/trunk/cherokee/util.c (modified) (4 diffs)
- cherokee/trunk/cherokee/util.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
cherokee/trunk/ChangeLog
r1753 r1754 1 2008-08-06 Alvaro Lopez Ortega <alvaro@alobbs.com> 2 3 * cherokee/fcgi_manager.c, cherokee/socket.c, cherokee/source.c, 4 cherokee/downloader_async.c, cherokee/common-internal.h, 5 cherokee/thread.c, cherokee/handler_file.c, cherokee/util.c, 6 cherokee/util.h, cherokee/handler_scgi.c, cherokee/connection.c, 7 cherokee/server.c, cherokee/logger_writer.c: Here is another patch 8 for a nasty bug that has been showing up every now and then since 9 long time ago. We catch ya! Hehe! Well, now, seriously: There was 10 a problem with random delays (a few milliseconds) that were being 11 caused by incorrect socket properties. 12 1 13 2008-08-06 Taher Shihadeh <taher@unixwars.com> 2 14 cherokee/trunk/cherokee/common-internal.h
r1591 r1754 125 125 #ifdef _WIN32 126 126 # define SOCK_ERRNO() WSAGetLastError() 127 # define CLOSE_ON_EXEC(h) ((void)0)128 127 #else 129 128 # define SOCK_ERRNO() errno 130 # define CLOSE_ON_EXEC(h) fcntl (h, F_SETFD, FD_CLOEXEC)131 129 #endif 132 133 130 134 131 cherokee/trunk/cherokee/connection.c
r1715 r1754 213 213 size_t crlf_len; 214 214 215 /* I/O cache entry reference 216 */ 215 217 if (conn->io_entry_ref != NULL) { 216 218 cherokee_iocache_entry_unref (&conn->io_entry_ref); 217 219 conn->io_entry_ref = NULL; 220 } 221 222 /* TCP cork 223 */ 224 if (conn->options & conn_op_tcp_cork) { 225 cherokee_connection_set_cork (conn, false); 226 BIT_UNSET (conn->options, conn_op_tcp_cork); 218 227 } 219 228 cherokee/trunk/cherokee/downloader_async.c
r1435 r1754 91 91 if (ret != ret_ok) return ret; 92 92 93 ret = cherokee_fd_set_nonblocking (down->socket.socket );93 ret = cherokee_fd_set_nonblocking (down->socket.socket, true); 94 94 if (ret != ret_ok) return ret; 95 95 cherokee/trunk/cherokee/fcgi_manager.c
r1175 r1754 192 192 TRACE (ENTRIES, "Connected sucessfully try=%d, fd=%d\n", try, mgr->socket.socket); 193 193 194 cherokee_fd_set_nonblocking (SOCKET_FD(&mgr->socket) );194 cherokee_fd_set_nonblocking (SOCKET_FD(&mgr->socket), true); 195 195 return ret_ok; 196 196 } cherokee/trunk/cherokee/handler_file.c
r1680 r1754 555 555 if (fhdl->using_sendfile) { 556 556 cherokee_connection_set_cork (conn, true); 557 BIT_SET (conn->options, conn_op_tcp_cork); 557 558 } 558 559 #endif … … 724 725 &sent); /* ssize_t *sent */ 725 726 726 /* cherokee_handler_file_init() activated the TCP_CORK flags.727 * After it, the header was sent. And now, the first728 * chunk of the file with sendfile(). It's time to turn729 * off again the TCP_CORK flag727 /* cherokee_handler_file_init() activated the TCP_CORK 728 * flags. Then the response header was sent. Now, the 729 * first chunk of the file with sendfile(), so it's 730 * time to turn off the TCP_CORK flag again. 730 731 */ 731 732 if (conn->options & conn_op_tcp_cork) { 732 733 cherokee_connection_set_cork (conn, false); 734 BIT_UNSET (conn->options, conn_op_tcp_cork); 733 735 } 734 736 cherokee/trunk/cherokee/handler_scgi.c
r1745 r1754 283 283 conn, 284 284 SOCKET_FD(&hdl->socket), 285 FDPOLL_MODE_WRITE, 285 FDPOLL_MODE_WRITE, 286 286 false); 287 287 if (ret != ret_ok) { cherokee/trunk/cherokee/logger_writer.c
r1301 r1754 241 241 cherokee_logger_writer_open (cherokee_logger_writer_t *writer) 242 242 { 243 ret_t ret; 244 243 245 switch (writer->type) { 244 246 case cherokee_logger_writer_syslog: … … 262 264 return ret_error; 263 265 } 264 CLOSE_ON_EXEC(writer->fd); 266 267 ret = cherokee_fd_set_closexec (writer->fd); 268 if (ret != ret_ok) 269 return ret; 270 265 271 return ret_ok; 266 272 cherokee/trunk/cherokee/server.c
r1727 r1754 424 424 set_server_fd_socket_opts (int socket) 425 425 { 426 ret_t ret; 426 427 int re; 427 428 int on; … … 430 431 /* Set 'close-on-exec' 431 432 */ 432 CLOSE_ON_EXEC(socket); 433 ret = cherokee_fd_set_closexec (socket); 434 if (ret != ret_ok) 435 return ret; 433 436 434 /* To re-bind without wait to TIME_WAIT 437 /* To re-bind without wait to TIME_WAIT. It prevents 2MSL 438 * delay on accept. 435 439 */ 436 440 on = 1; … … 458 462 #endif 459 463 460 /* SO_LINGER 464 /* SO_LINGER: 465 * Don't want to block on calls to close. 466 * 461 467 * kernels that map pages for IO end up failing if the pipe is full 462 468 * at exit and we take away the final buffer. this is really a kernel … … 473 479 * not be used in code intended to be portable. 474 480 * 475 * Give clients 20s to send first data packet476 */ 477 #if defined (TCP_DEFER_ACCEPT) && defined(SOL_TCP)478 on = 20;479 re = setsockopt (socket, SOL_ TCP, TCP_DEFER_ACCEPT, &on, sizeof(on));481 * Give clients 5s to send first data packet 482 */ 483 #ifdef TCP_DEFER_ACCEPT 484 on = 5; 485 re = setsockopt (socket, SOL_SOCKET, TCP_DEFER_ACCEPT, &on, sizeof(on)); 480 486 if (re != 0) return ret_error; 481 487 #endif … … 653 659 } 654 660 655 /* Set no-delay mode 656 */ 657 ret = cherokee_socket_set_nodelay (socket); 658 if (ret != ret_ok) return ret; 661 /* Set no-delay mode: 662 * If no clients are waiting, accept() will return -1 immediately 663 */ 664 ret = cherokee_fd_set_nodelay (socket->socket, true); 665 if (ret != ret_ok) 666 return ret; 659 667 660 668 /* Listen cherokee/trunk/cherokee/socket.c
r1746 r1754 685 685 cherokee_socket_accept_fd (int server_socket, int *new_fd, cherokee_sockaddr_t *sa) 686 686 { 687 ret_t ret; 687 688 socklen_t len; 688 689 int new_socket; 689 int tmp = 1;690 690 691 691 /* Get the new connection … … 720 720 } 721 721 722 /* Close-on-exec: Child processes won't inherit this fd 723 */ 724 cherokee_fd_set_closexec (new_socket); 725 722 726 /* Disable Nagle's algorithm for this connection 723 727 * so that there is no delay involved when sending data 724 728 * which don't fill up a full IP datagram. 725 729 */ 726 setsockopt (new_socket, IPPROTO_TCP, TCP_NODELAY, (const void *)&tmp, sizeof(tmp)); 727 728 /* Close-on-exec, really needed only 729 * if *CGI and / or process pipes are used. 730 */ 731 CLOSE_ON_EXEC (new_socket); 730 ret = cherokee_fd_set_nodelay (new_socket, true); 731 if (ret != ret_ok) { 732 PRINT_ERROR ("Could not disable Nagle's algorithm.\n"); 733 return ret_error; 734 } 732 735 733 736 /* Enables nonblocking I/O. 734 737 */ 735 cherokee_fd_set_nonblocking (new_socket); 738 ret = cherokee_fd_set_nonblocking (new_socket, true); 739 if (ret != ret_ok) { 740 PRINT_ERROR ("Could not set non-blocking.\n"); 741 return ret_error; 742 } 736 743 737 744 *new_fd = new_socket; … … 1886 1893 1887 1894 1888 ret_t1889 cherokee_socket_set_nodelay (cherokee_socket_t *socket)1890 {1891 int re;1892 int fd;1893 int flags;1894 1895 fd = SOCKET_FD(socket);1896 1897 #ifdef _WIN321898 flags = 1;1899 re = ioctlsocket (fd, FIONBIO, (u_long)&flags);1900 if (unlikely (re < 0))1901 return ret_error;1902 #else1903 flags = fcntl (fd, F_GETFL, 0);1904 if (unlikely (flags == -1))1905 return ret_error;1906 1907 re = fcntl (fd, F_SETFL, flags | O_NDELAY);1908 if (unlikely (re < 0))1909 return ret_error;1910 #endif1911 1912 return ret_ok;1913 }1914 1915 1916 1895 ret_t 1917 1896 cherokee_socket_set_cork (cherokee_socket_t *socket, cherokee_boolean_t enable) 1918 1897 { 1919 1898 #if defined(HAVE_TCP_CORK) || defined(HAVE_TCP_NOPUSH) 1920 int on;1899 int re; 1921 1900 int fd = socket->socket; 1922 1901 1923 if (enable) { 1924 on = 0; 1925 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof on); 1926 on = 1; 1927 setsockopt(fd, IPPROTO_TCP, TCP_CORK, &on, sizeof on); 1928 } else { 1929 on = 0; 1930 setsockopt(fd, IPPROTO_TCP, TCP_CORK, &on, sizeof on); 1931 on = 1; 1932 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof on); 1933 } 1902 cherokee_fd_set_nodelay (fd, ! enable); 1903 1904 re = setsockopt (fd, IPPROTO_TCP, TCP_CORK, &enable, sizeof(enable)); 1905 if (re < 0) { 1906 PRINT_ERRNO (errno, "ERROR: Setting TCP_CORK to fd %d: ${errno}\n", fd); 1907 return ret_error; 1908 } 1909 1934 1910 #else 1935 1911 UNUSED(socket); cherokee/trunk/cherokee/source.c
r1708 r1754 99 99 100 100 /* Set non-blocking */ 101 ret = cherokee_fd_set_nonblocking (sock->socket );101 ret = cherokee_fd_set_nonblocking (sock->socket, true); 102 102 if (ret != ret_ok) 103 103 PRINT_ERRNO (errno, "Failed to set nonblocking (fd=%d): ${errno}\n", … … 119 119 120 120 /* Set non-blocking */ 121 ret = cherokee_fd_set_nonblocking (sock->socket );121 ret = cherokee_fd_set_nonblocking (sock->socket, true); 122 122 if (ret != ret_ok) 123 123 PRINT_ERRNO (errno, "Failed to set nonblocking (fd=%d): ${errno}\n", cherokee/trunk/cherokee/thread.c
r1715 r1754 492 492 conn->keepalive--; 493 493 494 /* TCP cork495 */496 if (conn->options & conn_op_tcp_cork) {497 cherokee_connection_set_cork (conn, false);498 }499 500 494 /* Clean the connection 501 495 */ … … 604 598 */ 605 599 if ((conn->phase != phase_shutdown) && 600 (conn->phase != phase_lingering) && 606 601 (conn->phase != phase_reading_header || conn->incoming_header.len <= 0)) 607 602 { … … 612 607 case -1: 613 608 conns_freed++; 614 purge_closed_connection (thd, conn);609 purge_closed_connection (thd, conn); 615 610 continue; 616 611 case 0: … … 1184 1179 1185 1180 case phase_shutdown: 1186 1187 1181 ret = cherokee_connection_shutdown_wr (conn); 1188 1182 switch (ret) { … … 1203 1197 } 1204 1198 /* fall down */ 1205 1199 1206 1200 case phase_lingering: 1207 1201 ret = cherokee_connection_linger_read (conn); cherokee/trunk/cherokee/util.c
r1708 r1754 46 46 #endif 47 47 48 #ifdef HAVE_NETINET_IN_H 49 # include <netinet/in.h> 50 #endif 51 #ifdef HAVE_NETINET_TCP_H 52 # include <netinet/tcp.h> 53 #endif 54 48 55 #ifdef HAVE_SYS_FILIO_H 49 56 # include <sys/filio.h> /* defines FIONBIO and FIONREAD */ … … 67 74 # include <syslog.h> 68 75 #endif 76 69 77 70 78 #if defined(HAVE_GNUTLS) … … 790 798 791 799 800 ret_t 801 cherokee_fd_set_nodelay (int fd, cherokee_boolean_t enable) 802 { 803 int re; 804 int flags; 805 806 /* TCP_NODELAY: Disable the Nagle algorithm. This means that 807 * segments are always sent as soon as possible, even if there 808 * is only a small amount of data. When not set, data is 809 * buffered until there is a sufficient amount to send out, 810 * thereby avoiding the frequent sending of small packets, 811 * which results in poor utilization of the network. 812 */ 813 #ifdef _WIN32 814 re = ioctlsocket (fd, FIONBIO, (u_long) &enable); 815 #else 816 flags = fcntl (fd, F_GETFL, 0); 817 if (unlikely (flags == -1)) { 818 PRINT_ERRNO (errno, "ERROR: fcntl/F_GETFL fd %d: ${errno}\n", fd); 819 return ret_error; 820 } 821 822 if (enable) 823 BIT_SET (flags, O_NDELAY); 824 else 825 BIT_UNSET (flags, O_NDELAY); 826 827 re = fcntl (fd, F_SETFL, flags); 828 #endif 829 if (unlikely (re < 0)) { 830 PRINT_ERRNO (errno, "ERROR: Setting O_NDELAY to fd %d: ${errno}\n", fd); 831 return ret_error; 832 } 833 834 return ret_ok; 835 } 836 792 837 ret_t 793 cherokee_fd_set_nonblocking (int fd )838 cherokee_fd_set_nonblocking (int fd, cherokee_boolean_t enable) 794 839 { 795 840 int re; … … 797 842 798 843 #ifdef _WIN32 799 tmp = ioctlsocket (fd, FIONBIO, (u_long *)&tmp);844 re = ioctlsocket (fd, FIONBIO, (u_long *) &enable); 800 845 #else 801 846 flags = fcntl (fd, F_GETFL, 0); 802 847 if (flags < 0) { 803 PRINT_ERRNO (errno, "ERROR: fcntl/F_GETFL fd=%d: ${errno}\n", fd); 804 return ret_error; 805 } 806 807 flags |= O_NONBLOCK; 848 PRINT_ERRNO (errno, "ERROR: fcntl/F_GETFL fd %d: ${errno}\n", fd); 849 return ret_error; 850 } 851 852 if (enable) 853 BIT_SET (flags, O_NONBLOCK); 854 else 855 BIT_UNSET (flags, O_NONBLOCK); 856 808 857 re = fcntl (fd, F_SETFL, flags); 809 858 #endif 810 859 if (re < 0) { 811 PRINT_ERRNO (errno, "ERROR: Setting 'O_NONBLOCK' to socked fd=%d: ${errno}\n", fd); 812 return ret_error; 813 } 860 PRINT_ERRNO (errno, "ERROR: Setting O_NONBLOCK to fd %d: ${errno}\n", fd); 861 return ret_error; 862 } 863 864 return ret_ok; 865 } 866 867 868 ret_t 869 cherokee_fd_set_closexec (int fd) 870 { 871 #ifndef _WIN32 872 int re; 873 874 re = fcntl (fd, F_SETFD, FD_CLOEXEC); 875 if (re < 0) { 876 PRINT_ERRNO (errno, "ERROR: Setting FD_CLOEXEC to fd %d: ${errno}\n", fd); 877 return ret_error; 878 } 879 #endif 814 880 815 881 return ret_ok; cherokee/trunk/cherokee/util.h
r1611 r1754 108 108 /* Misc 109 109 */ 110 ret_t cherokee_fd_set_nonblocking (int fd); 110 ret_t cherokee_fd_set_nonblocking (int fd, cherokee_boolean_t enable); 111 ret_t cherokee_fd_set_nodelay (int fd, cherokee_boolean_t enable); 112 ret_t cherokee_fd_set_closexec (int fd); 111 113 112 114 ret_t cherokee_sys_fdlimit_get (cuint_t *limit);