You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Randy Terbush <ra...@zyzzyva.com> on 1997/01/08 05:04:15 UTC

Re: server timeouts and FIN_WAIT_2

> Is there something specific about the way Apache handles timeouts and/or
> connection closes now that could be causing connections left in FIN_WAIT_2?
> I can't see anything obvious in the source, but these are areas of the
> code I'm not intimately familiar with.
> 
> Did the basic way timeouts or closes are handled by the server change
> between Apache 1.1.1 and Apache 1.2 change in any way?
> 
> We seem to have some folks in c.w.i.s.u. who are convinced that this is all
> a problem with Apache 1.2.

lingering_close() is completely new to 1.2. (included below)


#ifndef NO_LINGCLOSE
static void lingering_close (int sd, server_rec *server_conf)
{
    int dummybuf[512];
    struct timeval tv;
    fd_set fds, fds_read, fds_err;
    int select_rv = 0, read_rv = 0;

    /* Close our half of the connection --- send client a FIN */

    shutdown (sd, 1);

    /* Set up to wait for readable data on socket... */

    FD_ZERO (&fds);
    FD_SET (sd, &fds);
    tv.tv_sec = server_conf->keep_alive_timeout;
    tv.tv_usec = 0;

    fds_read = fds; fds_err = fds;
   
    /* Wait for readable data or error condition on socket;
     * slurp up any data that arrives...
     */

#ifdef HPUX
    while ((select_rv = select (sd + 1, (int*)&fds_read, NULL, (int*)&fds_err,
                &tv)) > 0) {
#else
    while ((select_rv = select (sd + 1, &fds_read, NULL, &fds_err, &tv)) > 0) {
#endif
    if ((read_rv = read (sd, dummybuf, sizeof(dummybuf))) <= 0)
        break;
    else {
        fds_read = fds; fds_err = fds;
    }
    }
    
    /* Log any errors that occured (client closing their end isn't an error) */
   
    if (select_rv < 0)
    log_unixerr("select", NULL, "lingering_close", server_conf);
    else if (read_rv < 0 && errno != ECONNRESET)
    log_unixerr("read", NULL, "lingering_close", server_conf);

    /* Should now have seen final ack.  Safe to finally kill socket */

    shutdown (sd, 2);
    close (sd);
}
#endif