Changeset 764

Show
Ignore:
Timestamp:
05/29/07 22:42:50 (2 years ago)
Author:
alo
Message:

--

Files:

Legend:

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

    r745 r764  
     12007-05-22  A.D.F  <adefacc@tin.it> 
     2 
     3        * cherokee/macros.h: 
     4        - use saner values in defines; 
     5 
     6        * cherokee/thread.h: 
     7        - added new fields to struct cherokee_thread_t 
     8          in order to keep exact numbers of connections per thread; 
     9        - added new parameter to cherokee_thread_new(); 
     10        - added new functions (for SINGLE THREAD): 
     11                cherokee_thread_accept_on(); 
     12                cherokee_thread_accept_off(); 
     13 
     14        * cherokee/thread.c: 
     15        - cherokee_thread_new(): 
     16          - added new test conditions, calculation 
     17            of conns_accept limit, etc.; 
     18 
     19        -cherokee_thread_step_SINGLE_THREAD() and 
     20          cherokee_thread_step_MULTI_THREAD(): 
     21          - added code to disable accepting new connections 
     22            when there are no more free slots (100% full) 
     23            and to reenable accepting new connections 
     24            when the number of connections is below 95% - 99%; 
     25          - removed calls to cherokee_fdpoll_is_full() 
     26            (by using #ifdef 0 ... #endif) because now 
     27            we test the number of open connections and 
     28            because cherokee_fdpoll_add() tests upper limit 
     29            and returns error if it is reached; 
     30          - now cherokee_fdpoll_watch() is always called 
     31            in order to avoid a busy wait loop when 
     32            there are no more free connection slots. 
     33 
     34        - process_active_connections(): 
     35          - added tests on total server number of open connections, 
     36            if the number is > max_keepalive limit 
     37            then keepalive is disabled until that number 
     38            goes down (high water principle); 
     39            this is done because if the server reaches the max number 
     40            of connections and open connections are kept alive, 
     41            then the server is no more able to accept new connections 
     42            (for minutes or even for hours); 
     43 
     44        - other minor space cleanups. 
     45 
     46        * cherokee/server.c: 
     47        - removed local define MIN_SPARE_FDS; 
     48        - added local define MIN_LISTEN_FDS; 
     49        - better distribution of spare fds for each thread; 
     50        - forced a minimum number of fds per thread by 
     51          lowering the number of requested threads to reach 
     52          a minimum number as set in macros.h; 
     53        - now if srv->thread_num == 1 then 
     54          cherokee_thread_step_SINGLE_THREAD() is called 
     55          even if the server has been compiled with HAVE_PTHREAD 1 
     56          (this speedup connection handling by 2% - 3%); 
     57        - set max_keepalive limit to 93% of max. number of connections 
     58          so that server tries to close connections before 
     59          it reaches 100% of opened connections (this should prevent 
     60          the scenario where server is not able to accept new connections 
     61          for minutes or even hours); 
     62        - print_banner(), 
     63          added new information about max. server connections, etc.; 
     64        - minor space cleanups; 
     65 
     66        * cherokee/handler_server_info.c: 
     67        - added new info about current number of server connections 
     68          (which is different from the number of active connections); 
     69 
     70        * cherokee/socket.c: 
     71        - cherokee_socket_accept_fd(), 
     72          now ECONNABORTED returns ret_deny, 
     73          so callers should call this function again (retry loop) 
     74          instead of giving up and execute the process phase 
     75          (this should speed up a lot the server when clients 
     76           try to connect and abort connections before they 
     77           are accepted by server). 
     78         
    1792007-05-06  Alvaro Lopez Ortega  <alvaro@alobbs.com> 
    280 
  • cherokee/trunk/cherokee/handler_server_info.c

    r655 r764  
    254254build_connections_table_content (cherokee_buffer_t *buf, cherokee_server_t *srv) 
    255255{ 
    256         cuint_t active; 
    257         cuint_t reusable; 
    258          
     256        cuint_t conns_num = 0; 
     257        cuint_t active = 0; 
     258        cuint_t reusable = 0; 
     259         
     260        cherokee_server_get_conns_num (srv, &conns_num); 
    259261        cherokee_server_get_active_conns (srv, &active); 
    260262        cherokee_server_get_reusable_conns (srv, &reusable); 
    261263 
     264        table_add_row_int (buf, "Open connections", conns_num); 
    262265        table_add_row_int (buf, "Active connections", active); 
    263266        table_add_row_int (buf, "Reusable connections", reusable); 
  • cherokee/trunk/cherokee/macros.h

    r731 r764  
    102102#define MIN_SYSTEM_FD_NUM             20        /* range: 16 - 64 */ 
    103103#define MIN_SPARE_FDS                 10        /* range:  8 - 20 */ 
    104 #define MIN_MAX_FDS                    4       /* range:  4 ... 32000 */ 
    105 #define MIN_THR_FDS                    4       /* range:  4 ... 32000 */ 
     104#define MIN_MAX_FDS                    8       /* range:  8 ... 65000 */ 
     105#define MIN_THR_FDS                    8       /* range:  8 ... 65000 */ 
    106106 
    107107#if (MIN_SYSTEM_FD_NUM < 16)  
     
    111111#error MIN_SPARE_FDS too low, < 8 ! 
    112112#endif 
    113 #if (MIN_MAX_FDS < 4
    114 #error MIN_MAX_FDS too low, < 4
    115 #endif 
    116 #if (MIN_THR_FDS < 4
    117 #error MIN_THR_FDS too low, < 4
     113#if (MIN_MAX_FDS < 8
     114#error MIN_MAX_FDS too low, < 8
     115#endif 
     116#if (MIN_THR_FDS < 8
     117#error MIN_THR_FDS too low, < 8
    118118#endif 
    119119#if (MIN_THR_FDS > MIN_MAX_FDS) 
    120120#error MIN_THR_FDS too high, > MIN_MAX_FDS ! 
    121121#endif 
    122 #if (((MIN_SYSTEM_FD_NUM - MIN_SPARE_FDS) / 2) < MIN_MAX_FDS) 
     122#if ((MIN_SYSTEM_FD_NUM - MIN_SPARE_FDS) < MIN_MAX_FDS) 
    123123#error MIN_SYSTEM_FD_NUM too low or MIN_SPARE FDS too high ! 
    124124#endif 
     
    199199        type * obj = (type *) malloc(sizeof(type)); \ 
    200200        return_if_fail (obj != NULL, ret_nomem)  
     201 
     202/* We assume to have a C ANSI free(). 
     203 */ 
     204#define CHEROKEE_FREE(obj) \ 
     205        do {            \ 
     206        free (obj);     \ 
     207        (obj) = NULL;   \ 
     208        } while (0) 
    201209 
    202210#define CHEROKEE_TEMP(obj, size)                 \ 
  • cherokee/trunk/cherokee/server-protected.h

    r597 r764  
    122122        cherokee_poll_type_t       fdpoll_method; 
    123123 
     124        /* Connection related. 
     125         */ 
     126        int                        max_conns; 
     127        int                        max_keepalive_conns; 
     128 
    124129        /* Networking config 
    125130         */ 
  • cherokee/trunk/cherokee/server.c

    r731 r764  
    9191#define ENTRIES "core,server" 
    9292 
    93 /* Number of spare fds, used for stdin, stdout, stderr, etc. 
    94  * Set it between 5 and 20. 
     93/* Number of listen fds (HTTP + HTTPS) 
    9594 */ 
    96 #define MIN_SPARE_FDS  10 
     95#define MAX_LISTEN_FDS 2 
    9796 
    9897ret_t 
     
    156155        n->max_fds         = -1; 
    157156        n->system_fd_limit = -1; 
     157        n->max_conns       =  0; 
     158        n->max_keepalive_conns =  0; 
    158159        n->max_conn_reuse  = -1; 
    159160 
     
    397398        int error; 
    398399 
    399 /*         /\* Get user information */ 
    400 /*       *\/ */ 
    401 /*      ent = getpwuid (srv->user); */ 
    402 /*      if (ent == NULL) { */ 
    403 /*              PRINT_ERROR ("Can't get username for UID %d\n", srv->user); */ 
    404 /*              return ret_error; */ 
    405 /*      } */ 
    406          
     400#if 0 
     401        /* Get user information 
     402        */ 
     403        ent = getpwuid (srv->user); 
     404        if (ent == NULL) { 
     405                PRINT_ERROR ("Can't get username for UID %d\n", srv->user); 
     406                return ret_error; 
     407        } 
     408#endif 
     409 
    407410        /* Reset `groups' attributes. 
    408411         */ 
     
    641644        /* File descriptor limit 
    642645         */ 
    643         cherokee_buffer_add_va (&n, ", %d fds system limit, max. %d connections", srv->system_fd_limit, srv->max_fds); 
     646        cherokee_buffer_add_va (&n, ", %d fds system limit, max. %d connections", srv->system_fd_limit, srv->max_conns); 
    644647 
    645648        /* Threading stuff 
     
    647650        if (srv->thread_num <= 1) { 
    648651                cherokee_buffer_add_str (&n, ", single thread"); 
     652                cherokee_buffer_add_va (&n, ", %d fds per thread", srv->max_fds);        
    649653        } else { 
    650654                cherokee_buffer_add_va (&n, ", %d threads", srv->thread_num); 
     
    738742{        
    739743        ret_t ret; 
    740         int   i, fds_per_thread, fds_per_thread1
     744        int   i, fds_per_thread, fds_per_thread1, conns_per_thread
    741745#ifdef HAVE_PTHREAD 
    742746        int   thr_fds, spare_fds; 
    743747#endif 
     748 
     749        /* Reset max. conns value 
     750         */ 
     751        srv->max_conns = 0; 
     752        srv->max_keepalive_conns = 0; 
    744753 
    745754        /* Verify max_fds value 
     
    759768        srv->thread_num = 1; 
    760769#endif 
    761         fds_per_thread = srv->max_fds / srv->thread_num; 
     770 
     771        fds_per_thread1 = fds_per_thread = srv->max_fds / srv->thread_num; 
     772 
    762773#ifdef HAVE_PTHREAD 
    763774        thr_fds = fds_per_thread * srv->thread_num; 
    764775        spare_fds = srv->max_fds - thr_fds; 
    765 #endif 
    766         fds_per_thread1 = fds_per_thread; 
    767         if (spare_fds > 0) { 
    768                 spare_fds--; 
    769                 fds_per_thread1++; 
    770         } 
     776 
     777        /* Add a couple more fds to this thread, 
     778         * this is useful if we are using a huge number of threads 
     779         * (i.e. 1000 or more) and we don't want to leave lots of 
     780         * unused fds. 
     781         */ 
     782        if (spare_fds >= 2) { 
     783                spare_fds -= 2; 
     784                fds_per_thread1 += 2; 
     785        } 
     786#else 
     787        fds_per_thread1 -= MAX_LISTEN_FDS; 
     788#endif 
     789        /* Max. number of connections is halved because opening a new file 
     790         * or using a socket to connect to an external helper 
     791         * might be required to satisfy a request coming from an accepted 
     792         * and thus already open connection. 
     793         */ 
     794        conns_per_thread = fds_per_thread1 / 2; 
     795        srv->max_conns += conns_per_thread; 
     796        fds_per_thread1 += MAX_LISTEN_FDS; 
    771797 
    772798        /* Create the main thread 
    773799         */ 
    774800        ret = cherokee_thread_new (&srv->main_thread, srv, thread_sync,  
    775                                    srv->fdpoll_method, srv->system_fd_limit, fds_per_thread1); 
     801                        srv->fdpoll_method, srv->system_fd_limit, 
     802                        fds_per_thread1, conns_per_thread); 
    776803        if (unlikely(ret < ret_ok)) 
    777804                return ret; 
     
    780807         * add the server socket to the fdpoll of the sync thread 
    781808         */ 
    782 #ifndef HAVE_PTHREAD 
    783         ret = cherokee_fdpoll_add (srv->main_thread->fdpoll, S_SOCKET_FD(srv->socket), FDPOLL_MODE_READ); 
    784         if (unlikely(ret < ret_ok)) return ret; 
    785  
    786         if (srv->tls_enabled) { 
    787                 ret = cherokee_fdpoll_add (srv->main_thread->fdpoll, S_SOCKET_FD(srv->socket_tls), FDPOLL_MODE_READ); 
    788                 if (unlikely(ret < ret_ok)) return ret; 
    789         } 
    790 #endif 
     809        if (srv->thread_num == 1) { 
     810                ret = cherokee_thread_accept_on (srv->main_thread); 
     811                if (unlikely(ret < ret_ok)) 
     812                        return ret; 
     813        } 
    791814 
    792815        /* If Cherokee has been compiled in multi-thread mode, 
     
    797820                cherokee_thread_t *thread; 
    798821 
    799                 /* Add one more fd to this thread, 
     822                /* Add a couple more fds to this thread, 
    800823                 * this is useful if we are using a huge number of threads 
    801824                 * (i.e. 1000 or more) and we don't want to leave lots of 
     
    803826                 */ 
    804827                fds_per_thread1 = fds_per_thread; 
    805                 if (spare_fds > 0) { 
    806                         spare_fds--
    807                         fds_per_thread1++
     828                if (spare_fds >= 2) { 
     829                        spare_fds -= 2
     830                        fds_per_thread1 += 2
    808831                } 
     832                conns_per_thread = fds_per_thread1 / 2; 
     833                srv->max_conns += conns_per_thread; 
     834                fds_per_thread1 += MAX_LISTEN_FDS; 
    809835 
    810836                ret = cherokee_thread_new (&thread, srv, thread_async,  
    811                             srv->fdpoll_method, srv->system_fd_limit, fds_per_thread1); 
     837                                srv->fdpoll_method, srv->system_fd_limit, 
     838                                fds_per_thread1, conns_per_thread); 
    812839                if (unlikely(ret < ret_ok)) 
    813840                        return ret; 
     
    819846#endif 
    820847 
     848        /* Set keepalive limit for open connections. 
     849         * NOTE: this limit has to be lower (93%) 
     850         *       than conns_accept limit (95% - 99%) used for threads. 
     851         */ 
     852        srv->max_keepalive_conns = srv->max_conns - (srv->max_conns / 16); 
     853        if (srv->max_keepalive_conns + 6 > srv->max_conns) 
     854                srv->max_keepalive_conns = srv->max_conns - 6; 
     855 
     856        /* OK, return. 
     857         */ 
    821858        return ret_ok; 
    822859} 
     
    9771014         *       (i.e. FastCGI, SCGI, mirror, etc.). 
    9781015         */ 
    979         srv->max_fds = (srv->system_fd_limit - MIN_SPARE_FDS) / 2
     1016        srv->max_fds = (srv->system_fd_limit - MIN_SPARE_FDS)
    9801017        if (srv->max_fds < MIN_MAX_FDS) { 
    981                 PRINT_ERROR("Number of max. connection too low %d < %d !\n", srv->max_fds, MIN_MAX_FDS); 
     1018                PRINT_ERROR("Number of max. fds too low %d < %d !\n", srv->max_fds, MIN_MAX_FDS); 
    9821019                return ret_error; 
    9831020        } 
     
    12201257        ret_t ret; 
    12211258 
    1222         /* Get the time 
     1259        /* Get the server time. 
    12231260         */ 
    12241261        update_bogo_now (srv); 
    1225         ret = cherokee_thread_step (srv->main_thread, true); 
    1226  
     1262 
     1263        /* Execute thread step. 
     1264         */ 
     1265#ifndef HAVE_PTHREAD 
     1266        ret = cherokee_thread_step_SINGLE_THREAD (srv->main_thread); 
     1267#else 
     1268        if (srv->thread_num == 1) 
     1269                ret = cherokee_thread_step_SINGLE_THREAD (srv->main_thread); 
     1270        else 
     1271                ret = cherokee_thread_step_MULTI_THREAD (srv->main_thread, true); 
     1272#endif 
    12271273        /* Logger flush  
    12281274         */ 
     
    12441290         */ 
    12451291        if (unlikely (srv->wanna_reinit)) { 
    1246                 cherokee_server_reinit (srv); 
     1292                ret = cherokee_server_reinit (srv); 
     1293                if (ret != ret_ok) 
     1294                        return ret; 
    12471295        } 
    12481296         
     
    12521300        return ret_eagain; 
    12531301} 
     1302 
    12541303 
    12551304static ret_t  
     
    16811730 
    16821731ret_t  
     1732cherokee_server_get_conns_num (cherokee_server_t *srv, cuint_t *num) 
     1733{ 
     1734        cuint_t          conns_num = 0; 
     1735        cherokee_list_t *thread; 
     1736 
     1737        /* Open HTTP connections number 
     1738         */ 
     1739        list_for_each (thread, &srv->thread_list) { 
     1740                conns_num += THREAD(thread)->conns_num; 
     1741        } 
     1742         
     1743        conns_num += srv->main_thread->conns_num; 
     1744 
     1745        /* Return out parameters 
     1746         */ 
     1747        *num = conns_num; 
     1748 
     1749        return ret_ok; 
     1750} 
     1751 
     1752 
     1753ret_t  
    16831754cherokee_server_get_active_conns (cherokee_server_t *srv, cuint_t *num) 
    16841755{ 
     
    17111782         */ 
    17121783        list_for_each (thread, &srv->thread_list) { 
    1713                 list_for_each (i, &THREAD(thread)->reuse_list) { 
    1714                         reusable++; 
    1715                 } 
    1716         } 
    1717         list_for_each (i, &THREAD(srv->main_thread)->reuse_list) { 
    1718                 reusable++; 
    1719         } 
     1784                reusable += THREAD(thread)->reuse_list_num; 
     1785        } 
     1786        reusable += srv->main_thread->reuse_list_num; 
    17201787 
    17211788        /* Return out parameters 
  • cherokee/trunk/cherokee/server.h

    r690 r764  
    5757ret_t cherokee_server_write_pidfile      (cherokee_server_t *srv); 
    5858 
     59ret_t cherokee_server_get_conns_num      (cherokee_server_t *srv, cuint_t *num); 
    5960ret_t cherokee_server_get_active_conns   (cherokee_server_t *srv, cuint_t *num); 
    6061ret_t cherokee_server_get_reusable_conns (cherokee_server_t *srv, cuint_t *num); 
  • cherokee/trunk/cherokee/socket.c

    r706 r764  
    632632        new_socket = accept (server_socket, &sa->sa, &len); 
    633633        if (new_socket < 0) { 
    634                 return ret_error; 
     634                int err = SOCK_ERRNO(); 
     635                /* Caller has to retry the call on ret_deny. 
     636                 */ 
     637                switch (err) { 
     638#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN) 
     639                case EWOULDBLOCK: 
     640#endif   
     641                case EAGAIN:       
     642                case EINTR:        
     643                        /* no data or error. 
     644                         */ 
     645                        return ret_eagain; 
     646#ifdef ECONNABORTED 
     647                case ECONNABORTED: 
     648                        /* aborted connection, retry immediately 
     649                         */ 
     650                        return ret_deny; 
     651#endif 
     652                default: 
     653                        /* error 
     654                         */ 
     655                        return ret_error; 
     656                } 
     657                /* NOTREACHED */ 
    635658        }                
    636          
     659 
    637660        /* Disable Nagle's algorithm for this connection 
    638661         * so that there is no delay involved when sending data 
     
    11811204                if (re < 0) { 
    11821205                        int err = SOCK_ERRNO(); 
    1183                  
     1206 
    11841207                        switch (err) { 
    11851208#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN) 
  • cherokee/trunk/cherokee/thread.c

    r732 r764  
    142142         */ 
    143143        while (thread->exit == false) { 
    144                 cherokee_thread_step (thread, false); 
     144                cherokee_thread_step_MULTI_THREAD (thread, false); 
    145145        } 
    146146 
     
    173173 
    174174ret_t  
    175 cherokee_thread_new  (cherokee_thread_t **thd, void *server, cherokee_thread_type_t type,  
    176                       cherokee_poll_type_t fdpoll_type, int system_fd_num, int fd_num) 
     175cherokee_thread_new  ( 
     176        cherokee_thread_t **thd, void *server, cherokee_thread_type_t type,  
     177        cherokee_poll_type_t fdpoll_type, int system_fd_num, int fd_num, 
     178        int conns_max) 
    177179{ 
    178180        ret_t              ret; 
     181        int                conns_accept; 
    179182        cherokee_server_t *srv = SRV(server); 
    180         CHEROKEE_NEW_STRUCT (n, thread); 
     183        CHEROKEE_CNEW_STRUCT (1, n, thread); 
    181184 
    182185        /* Init 
     
    192195                ret = cherokee_fdpoll_new (&n->fdpoll, fdpoll_type, system_fd_num, fd_num); 
    193196 
    194         if (unlikely (ret != ret_ok))  
     197        if (unlikely (ret != ret_ok)) { 
     198                CHEROKEE_FREE(n); 
    195199                return ret; 
    196          
     200        } 
     201 
     202        n->exit              = false; 
     203        n->is_accepting_conns= false; 
     204 
     205        if (fd_num < conns_max || 
     206            conns_max < 4) { 
     207                cherokee_fdpoll_free (n->fdpoll); 
     208                CHEROKEE_FREE(n); 
     209                return ret_error; 
     210        } 
     211 
     212        /* Set upper accept limit to 95% - 99% of conns_max. 
     213         */ 
     214        if (conns_max > 40) { 
     215                conns_accept = conns_max - (conns_max / 20); 
     216 
     217                if (srv->thread_num > 16) { 
     218                        if (conns_accept < (conns_max - 4)) 
     219                                conns_accept = (conns_max - 4); 
     220                } else 
     221                if (srv->thread_num > 4) { 
     222                        if (conns_accept < (conns_max - 8)) 
     223                                conns_accept = (conns_max - 8); 
     224                } else 
     225                if (srv->thread_num > 1) { 
     226                        if (conns_accept < (conns_max - 10)) 
     227                                conns_accept = (conns_max - 10); 
     228                } else { 
     229                        if (conns_accept < (conns_max - 50)) 
     230                                conns_accept = (conns_max - 50); 
     231                } 
     232                if (conns_accept == conns_max) 
     233                        conns_accept -= 2; 
     234        } else { 
     235                conns_accept    = conns_max - 2; 
     236        } 
     237 
     238        n->conns_num         = 0; 
     239        n->conns_max         = conns_max; 
     240        n->conns_accept      = conns_accept; 
     241 
    197242        n->active_list_num   = 0; 
    198243        n->polling_list_num  = 0; 
    199244        n->reuse_list_num    = 0; 
    200245 
    201         n->exit              = false; 
    202246        n->pending_conns_num = 0; 
     247 
    203248        n->server            = server; 
    204249        n->thread_type       = type; 
     
    214259 
    215260        /* Temporary buffer used by utility functions 
    216                */ 
     261       */ 
    217262        cherokee_buffer_init (&n->tmp_buf1); 
    218263        cherokee_buffer_init (&n->tmp_buf2); 
     
    257302                /* Finally, create the system thread 
    258303                 */ 
    259                 pthread_create (&n->thread, &attr, thread_routine, n); 
     304                if (pthread_create (&n->thread, &attr, thread_routine, n) != 0) { 
     305                        cherokee_thread_free (n); 
     306                        return ret_error; 
     307                } 
    260308#else 
    261309                SHOULDNT_HAPPEN; 
     
    346394         */ 
    347395        cherokee_connection_mrproper (conn); 
     396 
     397        if (thread->conns_num > 0) 
     398                thread->conns_num--; 
    348399 
    349400        /* Add it to the reusable list 
     
    576627{ 
    577628        ret_t                  ret; 
     629        cuint_t                srv_conns_num = 0; 
    578630        off_t                  len; 
    579631        cherokee_list_t       *i, *tmp; 
     
    581633        cherokee_server_t     *srv  = SRV(thd->server); 
    582634 
     635        /* Get total connection count. 
     636         */ 
     637        cherokee_server_get_conns_num (srv, &srv_conns_num); 
     638 
    583639        /* Process active connections 
    584640         */ 
     
    591647                 */ 
    592648                if (conn->timeout < thd->bogo_now) { 
     649                        srv_conns_num--; 
    593650                        purge_closed_connection (thd, conn); 
    594651                        continue; 
     
    617674                        switch (num) { 
    618675                        case -1: 
     676                                srv_conns_num--; 
    619677                                purge_closed_connection(thd, conn); 
    620678                                continue; 
     
    643701                        case ret_eof: 
    644702                        case ret_error: 
     703                                srv_conns_num--; 
    645704                                purge_closed_connection (thd, conn); 
    646705                                continue; 
     
    648707                        default: 
    649708                                RET_UNKNOWN(ret); 
     709                                srv_conns_num--; 
    650710                                purge_closed_connection (thd, conn); 
    651711                                continue; 
     
    674734 
    675735                        case ret_error: 
     736                                srv_conns_num--; 
    676737                                purge_closed_connection (thd, conn); 
    677738                                continue; 
     
    679740                        default: 
    680741                                RET_UNKNOWN(ret); 
     742                                srv_conns_num--; 
    681743                                purge_closed_connection (thd, conn); 
    682744                                break; 
     
    711773 
    712774                        case ret_error: 
     775                                srv_conns_num--; 
    713776                                purge_closed_connection (thd, conn); 
    714777                                continue; 
     
    716779                        default: 
    717780                                RET_UNKNOWN(ret); 
     781                                srv_conns_num--; 
    718782                                purge_closed_connection (thd, conn); 
    719783                                continue; 
     
    740804                                        break; 
    741805                                case ret_error: 
     806                                        srv_conns_num--; 
    742807                                        purge_closed_connection (thd, conn); 
    743808                                        continue; 
    744809                                default: 
    745810                                        RET_UNKNOWN(ret); 
     811                                        srv_conns_num--; 
    746812                                        purge_closed_connection (thd, conn); 
    747813                                        continue; 
     
    812878                        case ret_eagain: 
    813879                                continue; 
    814                                  
     880 
    815881                        default: 
    816882                                cherokee_connection_setup_error_handler (conn); 
     
    10131079                        /* Server's "Keep-Alive" could be turned "Off" 
    10141080                         */ 
    1015                         if (srv->keepalive == false) { 
     1081                        if (conn->keepalive != 0 && 
     1082                           (srv->keepalive == false || 
     1083                            srv_conns_num >= (cuint_t) srv->max_keepalive_conns)) { 
    10161084                                conn->keepalive = 0; 
    10171085                        } 
     
    11291197                        case ret_eof: 
    11301198                        case ret_error: 
     1199                                srv_conns_num--; 
    11311200                                purge_closed_connection (thd, conn); 
    11321201                                continue; 
     
    11921261                                case ret_error: 
    11931262                                default:         
     1263                                        srv_conns_num--; 
    11941264                                        purge_closed_connection (thd, conn); 
    11951265                                        /* purge_maybe_lingering (thd, conn); */ 
     
    13181388        cherokee_connection_t *new_conn; 
    13191389 
    1320         /* Return if there're no new connections 
    1321          */ 
    1322         if (cherokee_fdpoll_check (thd->fdpoll, srv_socket, FDPOLL_MODE_READ) == 0) { 
     1390        /* Return if there're too many or no new connections 
     1391         */ 
     1392        if (thd->conns_num >= thd->conns_max) 
    13231393                return 0; 
     1394 
     1395        if (cherokee_fdpoll_check (thd->fdpoll, srv_socket, FDPOLL_MODE_READ) <= 0) { 
     1396                return 0; 
    13241397        } 
    13251398 
    13261399        /* Try to get a new connection 
    13271400         */ 
    1328         ret = cherokee_socket_accept_fd (srv_socket, &new_fd, &new_sa); 
    1329         if (ret < ret_ok) return 0; 
     1401        do { 
     1402                ret = cherokee_socket_accept_fd (srv_socket, &new_fd, &new_sa); 
     1403        } while (ret == ret_deny); 
     1404 
     1405        if (ret != ret_ok) 
     1406                return 0; 
    13301407 
    13311408        /* We got the new socket, now set it up in a new connection object 
     
    13691446        } 
    13701447 
     1448        thd->conns_num++; 
     1449 
    13711450        TRACE (ENTRIES, "new conn %p, fd %d\n", new_conn, new_fd); 
    13721451 
     
    13921471        /* If it is full, do not accept more! 
    13931472         */ 
     1473        if (unlikely (thd->conns_num >= thd->conns_max)) 
     1474                return 0; 
     1475 
     1476#if 0 
    13941477        if (unlikely (cherokee_fdpoll_is_full(thd->fdpoll))) { 
    13951478                return 0; 
    13961479        } 
     1480#endif 
    13971481 
    13981482        /* Got new connection 
     
    14241508 
    14251509ret_t  
    1426 cherokee_thread_step_SINGLE_THREAD (cherokee_thread_t *thd, cherokee_boolean_t dont_block) 
     1510cherokee_thread_accept_on (cherokee_thread_t *thd) 
     1511
     1512        ret_t ret; 
     1513 
     1514        if (thd->is_accepting_conns) 
     1515                return ret_ok; 
     1516 
     1517        /* Add server sockets to polling set. 
     1518         */ 
     1519        ret = cherokee_fdpoll_add (thd->fdpoll, 
     1520                S_SOCKET_FD(THREAD_SRV(thd)->socket), FDPOLL_MODE_READ); 
     1521        if (unlikely(ret < ret_ok)) 
     1522                return ret; 
     1523 
     1524#ifdef HAVE_TLS 
     1525        if (THREAD_SRV(thd)->tls_enabled) { 
     1526                ret = cherokee_fdpoll_add (thd->fdpoll, 
     1527                        S_SOCKET_FD(THREAD_SRV(thd)->socket_tls), FDPOLL_MODE_READ); 
     1528                if (unlikely(ret < ret_ok)) 
     1529                        return ret; 
     1530        } 
     1531#endif /* HAVE_TLS */ 
     1532 
     1533        /* Set flag and return. 
     1534         */ 
     1535        thd->is_accepting_conns = true; 
     1536 
     1537        return ret_ok; 
     1538
     1539 
     1540 
     1541ret_t  
     1542cherokee_thread_accept_off (cherokee_thread_t *thd) 
     1543
     1544        ret_t ret; 
     1545 
     1546        if (!thd->is_accepting_conns) 
     1547                return ret_ok; 
     1548 
     1549        /* Remove server sockets from polling set. 
     1550         */ 
     1551        ret = cherokee_fdpoll_del (thd->fdpoll, 
     1552                S_SOCKET_FD(THREAD_SRV(thd)->socket)); 
     1553        if (unlikely(ret < ret_ok)) 
     1554                return ret; 
     1555 
     1556#ifdef HAVE_TLS 
     1557        if (THREAD_SRV(thd)->tls_enabled) { 
     1558                ret = cherokee_fdpoll_del (thd->fdpoll, 
     1559                        S_SOCKET_FD(THREAD_SRV(thd)->socket_tls)); 
     1560                if (unlikely(ret < ret_ok)) 
     1561                        return ret; 
     1562        } 
     1563#endif /* HAVE_TLS */ 
     1564 
     1565        /* Set flag and return. 
     1566         */ 
     1567        thd->is_accepting_conns = false; 
     1568 
     1569        return ret_ok; 
     1570
     1571 
     1572 
     1573ret_t  
     1574cherokee_thread_step_SINGLE_THREAD (cherokee_thread_t *thd) 
    14271575{ 
    14281576        int                re; 
     1577        ret_t              ret; 
    14291578        cherokee_server_t *srv           = THREAD_SRV(thd); 
    14301579        int                fdwatch_msecs = srv->fdwatch_msecs; 
     
    14341583        try_to_update_bogo_now (thd); 
    14351584 
    1436         /* Reset the server socket 
     1585        /* Reset the server socket. 
    14371586         * cherokee_fdpoll_reset (thd->fdpoll, S_SOCKET_FD(srv->socket)); 
    14381587         */ 
    14391588 
    14401589        /* If the thread is full of connections, it should not 
    1441          * get new connections 
    1442          */ 
     1590         * get new connections. 
     1591         */ 
     1592        if (thd->conns_num >= thd->conns_max) { 
     1593                if (thd->is_accepting_conns) 
     1594                        ret = cherokee_thread_accept_off (thd); 
     1595        } 
     1596        else 
     1597        if (thd->conns_num < thd->conns_accept) { 
     1598                if (!thd->is_accepting_conns) 
     1599                        ret = cherokee_thread_accept_on (thd); 
     1600        } 
     1601 
     1602#if 0 
    14431603        if (unlikely (cherokee_fdpoll_is_full (thd->fdpoll))) { 
    14441604                goto out; 
    14451605        } 
     1606#endif 
    14461607 
    14471608        /* If thread has pending connections, it should do a  
     
    14541615 
    14551616        re = cherokee_fdpoll_watch (thd->fdpoll, fdwatch_msecs); 
    1456         if (re <= 0) goto out; 
     1617        if (re <= 0) 
     1618                goto out; 
    14571619 
    14581620        do { 
     
    14601622        } while (__should_accept_more_from_server (thd, re)); 
    14611623 
     1624#ifdef HAVE_TLS 
    14621625        if (srv->tls_enabled) { 
    14631626                do { 
     
    14651628                } while (__should_accept_more_from_server (thd, re)); 
    14661629        } 
     1630#endif /* HAVE_TLS */ 
    14671631 
    14681632out: 
     
    14851649        ret_t ret; 
    14861650 
     1651        /* In this case, thd->is_accepting_conns is alwasy true. 
     1652         */ 
    14871653        CHEROKEE_MUTEX_LOCK (mutex); 
    14881654         
     
    15231689        int   re; 
    15241690        ret_t ret; 
    1525         int   unlocked
     1691        int   unlocked = 1
    15261692