Commit d554b00f authored by Ryan Bloom's avatar Ryan Bloom
Browse files

Cleanup the worker MPM. We no longer re-use transaction

pools.  This incurs less overhead than shuffling the pools
around so that they can be re-used.  Remove one of the
queue's condition variables.  We just redefined the API to
state that you can't try to add more stuff than you allocated
segments for.

Submitted by:	  Aaron Bannert <aaron@clove.org>


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@91075 13f79535-47bb-0310-9956-ffa450edef68
parent f57781eb
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
Changes with Apache 2.0.26-dev

  *) Cleanup the worker MPM.  We no longer re-use transaction
     pools.  This incurs less overhead than shuffling the pools
     around so that they can be re-used.  Remove one of the
     queue's condition variables.  We just redefined the API to
     state that you can't try to add more stuff than you allocated
     segments for.  [Aaron Bannert <aaron@clove.org>]

  *) Fix SSL VPATH builds [Cody Sherr <csherr@covalent.net>]

  *) Fixed persistent connections when a request contains a body.
     [Greg Stein]

+7 −9
Original line number Diff line number Diff line
@@ -89,7 +89,6 @@ static apr_status_t ap_queue_destroy(void *data)
     * XXX: We should at least try to signal an error here, it is
     * indicative of a programmer error. -aaron */
    pthread_cond_destroy(&queue->not_empty);
    pthread_cond_destroy(&queue->not_full);
    pthread_mutex_destroy(&queue->one_big_mutex);

    return FD_QUEUE_SUCCESS;
@@ -107,8 +106,6 @@ int ap_queue_init(fd_queue_t *queue, int queue_capacity, apr_pool_t *a)
        return FD_QUEUE_FAILURE;
    if (pthread_cond_init(&queue->not_empty, NULL) != 0)
        return FD_QUEUE_FAILURE;
    if (pthread_cond_init(&queue->not_full, NULL) != 0)
        return FD_QUEUE_FAILURE;

    bounds = queue_capacity + 1;
    queue->head = queue->tail = 0;
@@ -136,9 +133,13 @@ int ap_queue_push(fd_queue_t *queue, apr_socket_t *sd, apr_pool_t *p)
        return FD_QUEUE_FAILURE;
    }

    /* Keep waiting until we wake up and find that the queue is not full. */
    while (ap_queue_full(queue)) {
        pthread_cond_wait(&queue->not_full, &queue->one_big_mutex);
    /* If the caller didn't allocate enough slots and tries to push
     * too many, too bad. */
    if (ap_queue_full(queue)) {
        if (pthread_mutex_unlock(&queue->one_big_mutex) != 0) {
            return FD_QUEUE_FAILURE;
        }
        return FD_QUEUE_OVERFLOW;
    }

    queue->data[queue->tail].sd = sd;
@@ -188,9 +189,6 @@ apr_status_t ap_queue_pop(fd_queue_t *queue, apr_socket_t **sd, apr_pool_t **p)
    }
    queue->blanks++;

    /* we just consumed a slot, so we're no longer full */
    pthread_cond_signal(&queue->not_full);

    if (pthread_mutex_unlock(&queue->one_big_mutex) != 0) {
        return FD_QUEUE_FAILURE;
    }
+1 −1
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@
#define FD_QUEUE_FAILURE -1 /* Needs to be an invalid file descriptor because
                               of queue_pop semantics */
#define FD_QUEUE_EINTR APR_EINTR
#define FD_QUEUE_OVERFLOW -2

struct fd_queue_elem_t {
    apr_socket_t      *sd;
@@ -87,7 +88,6 @@ struct fd_queue_t {
    int                blanks;
    pthread_mutex_t    one_big_mutex;
    pthread_cond_t     not_empty;
    pthread_cond_t     not_full;
    int                cancel_state;
};
typedef struct fd_queue_t fd_queue_t;
+6 −35
Original line number Diff line number Diff line
@@ -123,7 +123,6 @@ static int requests_this_child;
static int num_listensocks = 0;
static apr_socket_t **listensocks;
static fd_queue_t *worker_queue;
static fd_queue_t *pool_queue; /* a resource pool of context pools */

/* The structure used to pass unique initialization info to each thread */
typedef struct {
@@ -204,7 +203,6 @@ static void signal_workers(void)
    /* XXX: This will happen naturally on a graceful, and we don't care otherwise.
    ap_queue_signal_all_wakeup(worker_queue); */
    ap_queue_interrupt_all(worker_queue);
    ap_queue_interrupt_all(pool_queue);
}

AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
@@ -558,7 +556,6 @@ static void *listener_thread(apr_thread_t *thd, void * dummy)
    int thread_slot = ti->tid;
    apr_pool_t *tpool = apr_thread_pool_get(thd);
    apr_socket_t *csd = NULL;
    apr_socket_t *dummycsd = NULL;
    apr_pool_t *ptrans;		/* Pool for per-transaction stuff */
    apr_socket_t *sd = NULL;
    int n;
@@ -644,19 +641,8 @@ static void *listener_thread(apr_thread_t *thd, void * dummy)
        }
    got_fd:
        if (!workers_may_exit) {

            /* pull the next available transaction pool from the queue */
            if ((rv = ap_queue_pop(pool_queue, &dummycsd, &ptrans))
                != FD_QUEUE_SUCCESS) {
                if (rv == FD_QUEUE_EINTR) {
                    goto got_fd;
                }
                else { /* got some error in the queue */
                    csd = NULL;
                    ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, 
                        "ap_queue_pop");
                }
            }
            /* create a new transaction pool for each accepted socket */
            apr_pool_create(&ptrans, tpool);

            if ((rv = apr_accept(&csd, sd, ptrans)) != APR_SUCCESS) {
                csd = NULL;
@@ -692,7 +678,9 @@ static void *listener_thread(apr_thread_t *thd, void * dummy)
    ap_scoreboard_image->parent[process_slot].quiescing = 1;
    kill(ap_my_pid, SIGTERM);

/* Unsure if this can be safely uncommented. -aaron
    apr_thread_exit(thd, APR_SUCCESS);
*/
    return NULL;
}

@@ -718,12 +706,7 @@ static void *worker_thread(apr_thread_t *thd, void * dummy)
        }
        process_socket(ptrans, csd, process_slot, thread_slot);
        requests_this_child--; /* FIXME: should be synchronized - aaron */

        /* get this transaction pool ready for the next request */
        apr_pool_clear(ptrans);
        /* don't bother checking if we were interrupted in ap_queue_push,
         * because we're going to check workers_may_exit right now anyway. */
        ap_queue_push(pool_queue, NULL, ptrans);
        apr_pool_destroy(ptrans);
    }

    ap_update_child_status(process_slot, thread_slot,
@@ -758,24 +741,12 @@ static void *start_threads(apr_thread_t *thd, void *dummy)
    int i = 0;
    int threads_created = 0;
    apr_thread_t *listener;
    apr_pool_t *ptrans;
    apr_socket_t *dummycsd = NULL;

    /* We must create the fd queues before we start up the listener
     * and worker threads. */
    worker_queue = apr_pcalloc(pchild, sizeof(fd_queue_t));
    worker_queue = apr_pcalloc(pchild, sizeof(*worker_queue));
    ap_queue_init(worker_queue, ap_threads_per_child, pchild);

    /* create the resource pool of available transaction pools */
    pool_queue = apr_pcalloc(pchild, sizeof(fd_queue_t));
    ap_queue_init(pool_queue, ap_threads_per_child, pchild);
    /* fill the pool_queue with real pools */
    for (i = 0; i < ap_threads_per_child; i++) {
        ptrans = NULL;
        apr_pool_create(&ptrans, pchild);
        ap_queue_push(pool_queue, dummycsd, ptrans);
    }

    my_info = (proc_info *)malloc(sizeof(proc_info));
    my_info->pid = my_child_num;
    my_info->tid = i;