Changeset 389

Show
Ignore:
Timestamp:
09/04/06 20:05:08 (2 years ago)
Author:
alo
Message:

--

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • cherokee/trunk/cherokee/connection-protected.h

    r386 r389  
    7878        phase_send_headers, 
    7979        phase_steping, 
     80        phase_shutdown, 
    8081        phase_lingering 
    8182} cherokee_connection_phase_t; 
  • cherokee/trunk/cherokee/connection.c

    r386 r389  
    816816cherokee_connection_pre_lingering_close (cherokee_connection_t *conn) 
    817817{ 
    818         ret_t  ret; 
    819         size_t readed = 0; 
    820  
    821818        /* At this point, we don't want to follow the TLS protocol 
    822819         * any longer. 
     
    824821        conn->socket.is_tls = non_TLS; 
    825822 
     823        /* Set the timeout for future linger read(s) leaving the 
     824         * non-blocking mode. 
     825         */ 
     826        conn->timeout = CONN_THREAD(conn)->bogo_now + (MSECONS_TO_LINGER / 1000) + 1; 
     827 
    826828        /* Shut down the socket for write, which will send a FIN to 
    827829         * the peer. If shutdown fails then the socket is unusable. 
    828          */ 
    829         ret = cherokee_socket_shutdown (&conn->socket, SHUT_WR); 
    830         if (unlikely (ret != ret_ok)) return ret; 
    831  
    832         /* Set the timeout leaving the non-blocking mode 
    833          */ 
    834         conn->timeout = CONN_THREAD(conn)->bogo_now + (MSECONS_TO_LINGER / 1000) + 1; 
    835  
    836         return cherokee_connection_linger_read (conn); 
     830         */ 
     831        return cherokee_socket_shutdown (&conn->socket, SHUT_WR); 
    837832} 
    838833 
     
    857852                        return ret; 
    858853                case ret_eagain: 
    859                         TRACE(ENTRIES, "readed %d, eagain (linger)\n", readed); 
     854                        TRACE(ENTRIES, "readed %d, eagain\n", readed); 
    860855                        return ret; 
    861856                case ret_ok: 
    862                         TRACE(ENTRIES, "readed %d, ok/eagain (linger)\n", readed); 
     857                        TRACE(ENTRIES, "readed %d, ok/eagain\n", readed); 
    863858                        if (readed > 0 && --retries > 0) 
    864859                                continue; 
  • cherokee/trunk/cherokee/server.c

    r386 r389  
    16941694 
    16951695                        if (conn->id == id) { 
    1696                                 cherokee_connection_pre_lingering_close (conn); 
    1697                                 conn->phase = phase_lingering; 
    1698                                 return ret_ok; 
     1696                                if ((conn->phase != phase_nothing) &&  
     1697                                    (conn->phase != phase_lingering)) 
     1698                                { 
     1699                                        conn->phase = phase_shutdown; 
     1700                                        return ret_ok; 
     1701                                } 
    16991702                        } 
    17001703                } 
  • cherokee/trunk/cherokee/socket.c

    r386 r389  
    484484        int re; 
    485485 
    486         if (socket->socket < 0) { 
    487                 return ret_error; 
    488         } 
     486        /* If the read side of the socket has been closed but the 
     487         * write side is not, then don't bother to call shutdown 
     488         * because the socket is going to be closed anyway. 
     489         */ 
     490        if (unlikely (socket->status == socket_closed)) 
     491                return ret_eof; 
     492         
     493        if (unlikely (socket->socket < 0)) 
     494                return ret_error; 
    489495 
    490496        re = shutdown (socket->socket, how);     
    491497 
    492         return (re == 0)? ret_ok : ret_error; 
     498        return (re == 0) ? ret_ok : ret_error; 
    493499} 
    494500 
     
    860866        int re; 
    861867 
     868        if (unlikely (socket->status == socket_closed)) 
     869                return ret_eof; 
     870 
    862871#ifdef _WIN32 
    863872        int i; 
  • cherokee/trunk/cherokee/thread.c

    r386 r389  
    6565        case phase_send_headers:      return "Send headers"; 
    6666        case phase_steping:           return "Step"; 
     67        case phase_shutdown:          return "Shutdown connection"; 
    6768        case phase_lingering:         return "Lingering close"; 
    6869        default: 
     
    323324purge_connection (cherokee_thread_t *thread, cherokee_connection_t *conn) 
    324325{ 
    325         /* Try last read, if last read returned eof, then no problem, 
    326          * otherwise it may avoid a nasty connection reset. 
     326        /* Try last read, if previous read/write returned eof, then no 
     327         * problem, otherwise it may avoid a nasty connection reset. 
    327328         */ 
    328329        if (conn->phase == phase_lingering) { 
     
    426427purge_maybe_lingering (cherokee_thread_t *thread, cherokee_connection_t *conn) 
    427428{ 
    428         ret_t                       ret; 
    429         cherokee_connection_phase_t old_phase; 
    430  
    431         /* Set lingering close 
    432          */ 
    433         old_phase = conn->phase;  
    434         conn->phase = phase_lingering; 
     429        ret_t ret; 
    435430 
    436431        if (conn->keepalive <= 0) { 
     432                conn->phase = phase_lingering; 
    437433                purge_closed_connection (thread, conn); 
    438434                return; 
    439435        } 
    440436 
    441         /* Shutdown writting, and try to read some trash 
     437        /* Shutdown writing, and try to read some trash 
    442438         */ 
    443439        ret = cherokee_connection_pre_lingering_close (conn); 
     
    447443                /* Ok, really lingering 
    448444                 */ 
     445                conn->phase = phase_lingering; 
    449446                conn_set_mode (thread, conn, socket_reading); 
    450447                return; 
    451448        default: 
    452                 conn->phase = old_phase; 
     449                /* Error: no linger and no last read, just close it 
     450                 */ 
    453451                purge_closed_connection (thread, conn); 
    454452                return; 
     
    469467 
    470468        /* If it isn't a keep-alive connection, it should try to 
    471          * perform a lingering close. (There is no need to disable TCP 
    472          * cork before shutdown) 
     469         * perform a lingering close (there is no need to disable TCP 
     470         * cork before shutdown or before a close). 
    473471         */ 
    474472        if (conn->keepalive <= 0) { 
     
    479477                        /* Ok, lingering 
    480478                         */ 
    481                        conn->phase = phase_lingering; 
    482                        return; 
     479                        conn->phase = phase_lingering; 
     480                        conn_set_mode (thread, conn, socket_reading); 
     481                        return; 
    483482                default: 
     483                        /* Error, no linger and no last read, just 
     484                         * close the connection. 
     485                         */ 
    484486                        purge_closed_connection (thread, conn); 
    485487                        return; 
     
    587589                } 
    588590 
    589                 /* Process?  
    590                  * Incoming buffer has information and it's reading the headers 
     591                /* Set process condition to true if it's shutdown 
     592                 * phase or it's reading the headers and incoming 
     593                 * buffer has data to be processed. 
    591594                 */ 
    592                 process = ((conn->phase == phase_reading_header) && (conn->incoming_header.len > 0)); 
    593  
    594                 // (conn->phase == phase_lingering) || ? 
     595                process = ((conn->phase == phase_shutdown) ||  
     596                           ((conn->phase == phase_reading_header) && (conn->incoming_header.len > 0))); 
    595597                         
    596598                /* Process the connection? 
     
    12071209                        break; 
    12081210                         
     1211                case phase_shutdown:  
     1212 
     1213                        ret = cherokee_connection_pre_lingering_close (conn); 
     1214                        switch (ret) { 
     1215                        case ret_ok: 
     1216                        case ret_eagain: 
     1217                                /* Ok, really lingering 
     1218                                 */ 
     1219                                conn->phase = phase_lingering; 
     1220                                conn_set_mode (thd, conn, socket_reading); 
     1221                                break; 
     1222                        default: 
     1223                                /* Error, no linger and no last read, 
     1224                                 * just close the connection. 
     1225                                 */ 
     1226                                purge_closed_connection (thd, conn); 
     1227                                continue; 
     1228                        } 
     1229                 
    12091230                case phase_lingering:  
    12101231 
     
    12271248                        SHOULDNT_HAPPEN; 
    12281249                } 
     1250 
    12291251        } /* list */     
    12301252