Commit d5406fe6 authored by Jim Jagielski's avatar Jim Jagielski
Browse files

Merge r1809273, r1814719 from trunk:

event: better apr_pollset_add() failure handling to avoid an (very unlikely)
worker vs listener race condition.



Follow up to r1809273: CHANGES entry.


Submitted by: ylavic
Reviewed by: ylavic, jim, covener


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1818963 13f79535-47bb-0310-9956-ffa450edef68
parent fdff2d4f
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
                                                         -*- coding: utf-8 -*-
Changes with Apache 2.4.30

  *) mpm_event: avoid a very unlikely race condition between the listener and
     the workers when the latter fails to add a connection to the pollset.
     [Yann Ylavic]

  *) mod_macro: fix usability of globally defined macros in .htaccess files.
     PR 57525.  [Jose Kahan <jose w3.org>, Yann Ylavic]

+0 −8
Original line number Diff line number Diff line
@@ -118,14 +118,6 @@ RELEASE SHOWSTOPPERS:
PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
  [ start all new proposals below, under PATCHES PROPOSED. ]

  *) mpm_event: avoid a very unlikely race condition between the listener and
     the workers when the latter fails to add a connection to the pollset.
     trunk patch: http://svn.apache.org/r1809273
                  http://svn.apache.org/r1814719 (CHANGES only)
     2.4.x patch: trunk works (modulo CHANGES)
                  svn merge -c 1809273,1814719 ^/httpd/httpd/trunk .
     +1: ylavic, jim, covener

  *) core: silently ignore a not existent file path when IncludeOptional is used.
     trunk patch: http://svn.apache.org/r1814968
     2.4.x patch: trunk works (modulo CHANGES)
+12 −14
Original line number Diff line number Diff line
@@ -306,6 +306,7 @@ static void TO_QUEUE_APPEND(struct timeout_queue *q, event_conn_state_t *el)
static void TO_QUEUE_REMOVE(struct timeout_queue *q, event_conn_state_t *el)
{
    APR_RING_REMOVE(el, timeout_list);
    APR_RING_ELEM_INIT(el, timeout_list);
    apr_atomic_dec32(q->total);
    --q->count;
}
@@ -797,17 +798,16 @@ static int start_lingering_close_blocking(event_conn_state_t *cs)
    apr_thread_mutex_lock(timeout_mutex);
    TO_QUEUE_APPEND(q, cs);
    rv = apr_pollset_add(event_pollset, &cs->pfd);
    apr_thread_mutex_unlock(timeout_mutex);
    if (rv != APR_SUCCESS && !APR_STATUS_IS_EEXIST(rv)) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, APLOGNO(03092)
                     "start_lingering_close: apr_pollset_add failure");
        apr_thread_mutex_lock(timeout_mutex);
        TO_QUEUE_REMOVE(q, cs);
        apr_thread_mutex_unlock(timeout_mutex);
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, APLOGNO(03092)
                     "start_lingering_close: apr_pollset_add failure");
        apr_socket_close(cs->pfd.desc.s);
        ap_push_pool(worker_queue_info, cs->p);
        return 0;
    }
    apr_thread_mutex_unlock(timeout_mutex);
    return 1;
}

@@ -1053,17 +1053,18 @@ read_request:
            apr_thread_mutex_lock(timeout_mutex);
            TO_QUEUE_APPEND(cs->sc->wc_q, cs);
            rc = apr_pollset_add(event_pollset, &cs->pfd);
            apr_thread_mutex_unlock(timeout_mutex);
            if (rc != APR_SUCCESS && !APR_STATUS_IS_EEXIST(rc)) {
                TO_QUEUE_REMOVE(cs->sc->wc_q, cs);
                apr_thread_mutex_unlock(timeout_mutex);
                ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf, APLOGNO(03465)
                             "process_socket: apr_pollset_add failure for "
                             "write completion");
                apr_thread_mutex_lock(timeout_mutex);
                TO_QUEUE_REMOVE(cs->sc->wc_q, cs);
                apr_thread_mutex_unlock(timeout_mutex);
                apr_socket_close(cs->pfd.desc.s);
                ap_push_pool(worker_queue_info, cs->p);
            }
            else {
                apr_thread_mutex_unlock(timeout_mutex);
            }
            return;
        }
        else if (c->keepalive != AP_CONN_KEEPALIVE || c->aborted ||
@@ -1099,18 +1100,17 @@ read_request:
        apr_thread_mutex_lock(timeout_mutex);
        TO_QUEUE_APPEND(cs->sc->ka_q, cs);
        rc = apr_pollset_add(event_pollset, &cs->pfd);
        apr_thread_mutex_unlock(timeout_mutex);
        if (rc != APR_SUCCESS && !APR_STATUS_IS_EEXIST(rc)) {
            TO_QUEUE_REMOVE(cs->sc->ka_q, cs);
            apr_thread_mutex_unlock(timeout_mutex);
            ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf, APLOGNO(03093)
                         "process_socket: apr_pollset_add failure for "
                         "keep alive");
            apr_thread_mutex_lock(timeout_mutex);
            TO_QUEUE_REMOVE(cs->sc->ka_q, cs);
            apr_thread_mutex_unlock(timeout_mutex);
            apr_socket_close(cs->pfd.desc.s);
            ap_push_pool(worker_queue_info, cs->p);
            return;
        }
        apr_thread_mutex_unlock(timeout_mutex);
    }
    else if (cs->pub.state == CONN_STATE_SUSPENDED) {
        apr_atomic_inc32(&suspended_count);
@@ -1394,7 +1394,6 @@ static void process_lingering_close(event_conn_state_t *cs, const apr_pollfd_t *
    rv = apr_pollset_remove(event_pollset, pfd);
    apr_thread_mutex_unlock(timeout_mutex);
    AP_DEBUG_ASSERT(rv == APR_SUCCESS ||  APR_STATUS_IS_NOTFOUND(rv));
    TO_QUEUE_ELEM_INIT(cs);

    rv = apr_socket_close(csd);
    AP_DEBUG_ASSERT(rv == APR_SUCCESS);
@@ -1673,7 +1672,6 @@ static void * APR_THREAD_FUNC listener_thread(apr_thread_t * thd, void *dummy)
                    TO_QUEUE_REMOVE(remove_from_q, cs);
                    rc = apr_pollset_remove(event_pollset, &cs->pfd);
                    apr_thread_mutex_unlock(timeout_mutex);
                    TO_QUEUE_ELEM_INIT(cs);

                    /*
                     * Some of the pollset backends, like KQueue or Epoll