Changeset 1754

Show
Ignore:
Timestamp:
08/06/08 18:58:18 (5 months ago)
Author:
alo
Message:

--

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • cherokee/trunk/ChangeLog

    r1753 r1754  
     12008-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 
    1132008-08-06  Taher Shihadeh <taher@unixwars.com> 
    214 
  • cherokee/trunk/cherokee/common-internal.h

    r1591 r1754  
    125125#ifdef _WIN32 
    126126# define SOCK_ERRNO()      WSAGetLastError() 
    127 # define CLOSE_ON_EXEC(h)  ((void)0) 
    128127#else 
    129128# define SOCK_ERRNO()      errno 
    130 # define CLOSE_ON_EXEC(h)  fcntl (h, F_SETFD, FD_CLOEXEC) 
    131129#endif 
    132  
    133130 
    134131 
  • cherokee/trunk/cherokee/connection.c

    r1715 r1754  
    213213        size_t   crlf_len; 
    214214 
     215        /* I/O cache entry reference 
     216         */ 
    215217        if (conn->io_entry_ref != NULL) { 
    216218                cherokee_iocache_entry_unref (&conn->io_entry_ref); 
    217219                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);             
    218227        } 
    219228 
  • cherokee/trunk/cherokee/downloader_async.c

    r1435 r1754  
    9191        if (ret != ret_ok) return ret; 
    9292 
    93         ret = cherokee_fd_set_nonblocking (down->socket.socket); 
     93        ret = cherokee_fd_set_nonblocking (down->socket.socket, true); 
    9494        if (ret != ret_ok) return ret; 
    9595 
  • cherokee/trunk/cherokee/fcgi_manager.c

    r1175 r1754  
    192192        TRACE (ENTRIES, "Connected sucessfully try=%d, fd=%d\n", try, mgr->socket.socket); 
    193193 
    194         cherokee_fd_set_nonblocking (SOCKET_FD(&mgr->socket)); 
     194        cherokee_fd_set_nonblocking (SOCKET_FD(&mgr->socket), true); 
    195195        return ret_ok; 
    196196} 
  • cherokee/trunk/cherokee/handler_file.c

    r1680 r1754  
    555555        if (fhdl->using_sendfile) { 
    556556                cherokee_connection_set_cork (conn, true); 
     557                BIT_SET (conn->options, conn_op_tcp_cork);               
    557558        } 
    558559#endif 
     
    724725                                                &sent);                            /* ssize_t           *sent   */ 
    725726 
    726                 /* cherokee_handler_file_init() activated the TCP_CORK flags. 
    727                  * After it, the header was sent.  And now, the first 
    728                  * chunk of the file with sendfile().  It's time to turn 
    729                  * off again the TCP_CORK flag 
     727                /* 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. 
    730731                 */ 
    731732                if (conn->options & conn_op_tcp_cork) { 
    732733                        cherokee_connection_set_cork (conn, false); 
     734                        BIT_UNSET (conn->options, conn_op_tcp_cork); 
    733735                } 
    734736 
  • cherokee/trunk/cherokee/handler_scgi.c

    r1745 r1754  
    283283                                                           conn, 
    284284                                                           SOCKET_FD(&hdl->socket), 
    285                                                            FDPOLL_MODE_WRITE,  
     285                                                           FDPOLL_MODE_WRITE, 
    286286                                                           false); 
    287287                if (ret != ret_ok) { 
  • cherokee/trunk/cherokee/logger_writer.c

    r1301 r1754  
    241241cherokee_logger_writer_open (cherokee_logger_writer_t *writer) 
    242242{ 
     243        ret_t ret; 
     244 
    243245        switch (writer->type) { 
    244246        case cherokee_logger_writer_syslog: 
     
    262264                        return ret_error; 
    263265                } 
    264                 CLOSE_ON_EXEC(writer->fd); 
     266 
     267                ret = cherokee_fd_set_closexec (writer->fd); 
     268                if (ret != ret_ok) 
     269                        return ret; 
     270 
    265271                return ret_ok; 
    266272 
  • cherokee/trunk/cherokee/server.c

    r1727 r1754  
    424424set_server_fd_socket_opts (int socket) 
    425425{ 
     426        ret_t         ret; 
    426427        int           re; 
    427428        int           on; 
     
    430431        /* Set 'close-on-exec' 
    431432         */ 
    432         CLOSE_ON_EXEC(socket); 
     433        ret = cherokee_fd_set_closexec (socket); 
     434        if (ret != ret_ok) 
     435                return ret; 
    433436                 
    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. 
    435439         */ 
    436440        on = 1; 
     
    458462#endif   
    459463 
    460         /* SO_LINGER 
     464        /* SO_LINGER: 
     465         * Don't want to block on calls to close. 
     466         * 
    461467         * kernels that map pages for IO end up failing if the pipe is full 
    462468         * at exit and we take away the final buffer.  this is really a kernel 
     
    473479         * not be used in code intended to be portable. 
    474480         * 
    475          * Give clients 20s to send first data packet  
    476          */ 
    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)); 
    480486        if (re != 0) return ret_error; 
    481487#endif 
     
    653659        } 
    654660            
    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; 
    659667 
    660668        /* Listen 
  • cherokee/trunk/cherokee/socket.c

    r1746 r1754  
    685685cherokee_socket_accept_fd (int server_socket, int *new_fd, cherokee_sockaddr_t *sa) 
    686686{ 
     687        ret_t     ret; 
    687688        socklen_t len; 
    688689        int       new_socket; 
    689         int       tmp = 1; 
    690690 
    691691        /* Get the new connection 
     
    720720        } 
    721721 
     722        /* Close-on-exec: Child processes won't inherit this fd 
     723         */ 
     724        cherokee_fd_set_closexec (new_socket); 
     725 
    722726        /* Disable Nagle's algorithm for this connection 
    723727         * so that there is no delay involved when sending data 
    724728         * which don't fill up a full IP datagram. 
    725729         */ 
    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        } 
    732735 
    733736        /* Enables nonblocking I/O. 
    734737         */ 
    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        } 
    736743 
    737744        *new_fd = new_socket; 
     
    18861893 
    18871894 
    1888 ret_t  
    1889 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 _WIN32 
    1898         flags = 1; 
    1899         re = ioctlsocket (fd, FIONBIO, (u_long)&flags); 
    1900         if (unlikely (re < 0)) 
    1901                 return ret_error; 
    1902 #else 
    1903         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 #endif   
    1911  
    1912         return ret_ok; 
    1913 } 
    1914  
    1915  
    19161895ret_t 
    19171896cherokee_socket_set_cork (cherokee_socket_t *socket, cherokee_boolean_t enable) 
    19181897{ 
    19191898#if defined(HAVE_TCP_CORK) || defined(HAVE_TCP_NOPUSH) 
    1920         int on
     1899        int re
    19211900        int fd = socket->socket; 
    19221901 
    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         
    19341910#else 
    19351911        UNUSED(socket); 
  • cherokee/trunk/cherokee/source.c

    r1708 r1754  
    9999 
    100100                /* Set non-blocking */ 
    101                 ret = cherokee_fd_set_nonblocking (sock->socket); 
     101                ret = cherokee_fd_set_nonblocking (sock->socket, true); 
    102102                if (ret != ret_ok) 
    103103                        PRINT_ERRNO (errno, "Failed to set nonblocking (fd=%d): ${errno}\n", 
     
    119119 
    120120        /* Set non-blocking */ 
    121         ret = cherokee_fd_set_nonblocking (sock->socket); 
     121        ret = cherokee_fd_set_nonblocking (sock->socket, true); 
    122122        if (ret != ret_ok) 
    123123                PRINT_ERRNO (errno, "Failed to set nonblocking (fd=%d): ${errno}\n", 
  • cherokee/trunk/cherokee/thread.c

    r1715 r1754  
    492492        conn->keepalive--; 
    493493 
    494         /* TCP cork 
    495          */ 
    496         if (conn->options & conn_op_tcp_cork) { 
    497                 cherokee_connection_set_cork (conn, false); 
    498         } 
    499  
    500494        /* Clean the connection 
    501495         */ 
     
    604598                 */ 
    605599                if ((conn->phase != phase_shutdown) && 
     600                    (conn->phase != phase_lingering) && 
    606601                    (conn->phase != phase_reading_header || conn->incoming_header.len <= 0)) 
    607602                { 
     
    612607                        case -1: 
    613608                                conns_freed++; 
    614                                 purge_closed_connection(thd, conn); 
     609                                purge_closed_connection (thd, conn); 
    615610                                continue; 
    616611                        case 0: 
     
    11841179                         
    11851180                case phase_shutdown:  
    1186  
    11871181                        ret = cherokee_connection_shutdown_wr (conn); 
    11881182                        switch (ret) { 
     
    12031197                        } 
    12041198                        /* fall down */ 
    1205                  
     1199 
    12061200                case phase_lingering:  
    12071201                        ret = cherokee_connection_linger_read (conn); 
  • cherokee/trunk/cherokee/util.c

    r1708 r1754  
    4646#endif 
    4747 
     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 
    4855#ifdef HAVE_SYS_FILIO_H 
    4956# include <sys/filio.h>     /* defines FIONBIO and FIONREAD */ 
     
    6774# include <syslog.h> 
    6875#endif 
     76 
    6977 
    7078#if defined(HAVE_GNUTLS) 
     
    790798 
    791799 
     800ret_t 
     801cherokee_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 
    792837ret_t  
    793 cherokee_fd_set_nonblocking (int fd
     838cherokee_fd_set_nonblocking (int fd, cherokee_boolean_t enable
    794839{ 
    795840        int re; 
     
    797842 
    798843#ifdef _WIN32 
    799         tmp = ioctlsocket (fd, FIONBIO, (u_long *)&tmp); 
     844        re = ioctlsocket (fd, FIONBIO, (u_long *) &enable); 
    800845#else    
    801846        flags = fcntl (fd, F_GETFL, 0); 
    802847        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 
    808857        re = fcntl (fd, F_SETFL, flags); 
    809858#endif 
    810859        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 
     868ret_t  
     869cherokee_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 
    814880 
    815881        return ret_ok; 
  • cherokee/trunk/cherokee/util.h

    r1611 r1754  
    108108/* Misc 
    109109 */ 
    110 ret_t cherokee_fd_set_nonblocking (int fd); 
     110ret_t cherokee_fd_set_nonblocking (int fd, cherokee_boolean_t enable); 
     111ret_t cherokee_fd_set_nodelay     (int fd, cherokee_boolean_t enable); 
     112ret_t cherokee_fd_set_closexec    (int fd); 
    111113 
    112114ret_t cherokee_sys_fdlimit_get (cuint_t *limit);