Commit ce255155 authored by Stefan Eissing's avatar Stefan Eissing
Browse files

combined patches for alpha testing next release of http2

parent 0c37b947
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
                                                         -*- coding: utf-8 -*-

Changes with Apache 2.4.18
  *) mod_http2: reworked deallocation on connection shutdown and worker
     abort. Separate parent pool for all workers. worker threads are joined
     on planned worker shutdown.
     [Yann Ylavic, Stefan Eissing]
     

Changes with Apache 2.4.17
+1 −1
Original line number Diff line number Diff line
@@ -255,7 +255,7 @@ apr_status_t h2_session_process(h2_session *session)
            have_written = 1;
            wait_micros = 0;
        }
        else if (status == APR_EAGAIN) {
        else if (APR_STATUS_IS_EAGAIN(status)) {
            /* nop */
        }
        else if (status == APR_TIMEUP) {
+53 −6
Original line number Diff line number Diff line
@@ -47,6 +47,12 @@ void h2_io_destroy(h2_io *io)
    h2_io_cleanup(io);
}

void h2_io_rst(h2_io *io, int error)
{
    io->rst_error = error;
    io->eos_in = 1;
}

int h2_io_in_has_eos_for(h2_io *io)
{
    return io->eos_in || (io->bbin && h2_util_has_eos(io->bbin, 0));
@@ -124,16 +130,52 @@ apr_status_t h2_io_out_readx(h2_io *io,
                             h2_io_data_cb *cb, void *ctx, 
                             apr_size_t *plen, int *peos)
{
    apr_status_t status;
    
    if (io->eos_out) {
        *plen = 0;
        *peos = 1;
        return APR_SUCCESS;
    }
    
    if (cb == NULL) {
        /* just checking length available */
        return h2_util_bb_avail(io->bbout, plen, peos);
        status = h2_util_bb_avail(io->bbout, plen, peos);
    }
    else {
        status = h2_util_bb_readx(io->bbout, cb, ctx, plen, peos);
        if (status == APR_SUCCESS) {
            io->eos_out = *peos;
        }
    return h2_util_bb_readx(io->bbout, cb, ctx, plen, peos);
    }
    
    return status;
}

apr_status_t h2_io_out_write(h2_io *io, apr_bucket_brigade *bb, 
                             apr_size_t maxlen, int *pfile_handles_allowed)
{
    apr_status_t status;
    int start_allowed;
    
    if (io->eos_out) {
        apr_off_t len;
        /* We have already delivered an EOS bucket to a reader, no
         * sense in storing anything more here.
         */
        status = apr_brigade_length(bb, 1, &len);
        if (status == APR_SUCCESS) {
            if (len > 0) {
                /* someone tries to write real data after EOS, that
                 * does not look right. */
                status = APR_EOF;
            }
            /* cleanup, as if we had moved the data */
            apr_brigade_cleanup(bb);
        }
        return status;
    }
    
    /* Let's move the buckets from the request processing in here, so
     * that the main thread can read them when it has time/capacity.
     *
@@ -144,8 +186,11 @@ apr_status_t h2_io_out_write(h2_io *io, apr_bucket_brigade *bb,
     * many open files already buffered. Otherwise we will run out of
     * file handles.
     */
    int start_allowed = *pfile_handles_allowed;
    apr_status_t status;
    start_allowed = *pfile_handles_allowed;

    if (io->rst_error) {
        return APR_ECONNABORTED;
    }
    status = h2_util_move(io->bbout, bb, maxlen, pfile_handles_allowed, 
                          "h2_io_out_write");
    /* track # file buckets moved into our pool */
@@ -158,7 +203,9 @@ apr_status_t h2_io_out_write(h2_io *io, apr_bucket_brigade *bb,

apr_status_t h2_io_out_close(h2_io *io)
{
    if (!io->eos_out && !h2_util_has_eos(io->bbout, 0)) {
        APR_BRIGADE_INSERT_TAIL(io->bbout, 
                                apr_bucket_eos_create(io->bbout->bucket_alloc));
    }
    return APR_SUCCESS;
}
+7 −0
Original line number Diff line number Diff line
@@ -33,11 +33,13 @@ struct h2_io {
    apr_bucket_brigade *bbin;    /* input data for stream */
    int eos_in;
    int task_done;
    int rst_error;
    
    apr_size_t input_consumed;   /* how many bytes have been read */
    struct apr_thread_cond_t *input_arrived; /* block on reading */
    
    apr_bucket_brigade *bbout;   /* output data from stream */
    int eos_out;
    struct apr_thread_cond_t *output_drained; /* block on writing */
    
    struct h2_response *response;/* submittable response created */
@@ -58,6 +60,11 @@ h2_io *h2_io_create(int id, apr_pool_t *pool, apr_bucket_alloc_t *bucket_alloc);
 */
void h2_io_destroy(h2_io *io);

/**
 * Reset the stream with the given error code.
 */
void h2_io_rst(h2_io *io, int error);

/**
 * The input data is completely queued. Blocked reads will return immediately
 * and give either data or EOF.
+28 −23
Original line number Diff line number Diff line
@@ -78,19 +78,6 @@ h2_io *h2_io_set_get(h2_io_set *sp, int stream_id)
    return ps? *ps : NULL;
}

h2_io *h2_io_set_get_highest_prio(h2_io_set *set)
{
    h2_io *highest = NULL;
    int i;
    for (i = 0; i < set->list->nelts; ++i) {
        h2_io *io = h2_io_IDX(set->list, i);
        if (!highest /*|| io-prio even higher */ ) {
            highest = io;
        }
    }
    return highest;
}

static void h2_io_set_sort(h2_io_set *sp)
{
    qsort(sp->list->elts, sp->list->nelts, sp->list->elt_size, 
@@ -118,28 +105,46 @@ apr_status_t h2_io_set_add(h2_io_set *sp, h2_io *io)
    return APR_SUCCESS;
}

h2_io *h2_io_set_remove(h2_io_set *sp, h2_io *io)
static void remove_idx(h2_io_set *sp, int idx)
{
    int i;
    for (i = 0; i < sp->list->nelts; ++i) {
        h2_io *e = h2_io_IDX(sp->list, i);
        if (e == io) {
    int n;
    --sp->list->nelts;
            n = sp->list->nelts - i;
    n = sp->list->nelts - idx;
    if (n > 0) {
        /* Close the hole in the array by moving the upper
         * parts down one step.
         */
        h2_io **selts = (h2_io**)sp->list->elts;
                memmove(selts+i, selts+i+1, n * sizeof(h2_io*));
        memmove(selts + idx, selts + idx + 1, n * sizeof(h2_io*));
    }
}

h2_io *h2_io_set_remove(h2_io_set *sp, h2_io *io)
{
    int i;
    for (i = 0; i < sp->list->nelts; ++i) {
        h2_io *e = h2_io_IDX(sp->list, i);
        if (e == io) {
            remove_idx(sp, i);
            return e;
        }
    }
    return NULL;
}

h2_io *h2_io_set_pop_highest_prio(h2_io_set *set)
{
    /* For now, this just removes the first element in the set.
     * the name is misleading...
     */
    if (set->list->nelts > 0) {
        h2_io *io = h2_io_IDX(set->list, 0);
        remove_idx(set, 0);
        return io;
    }
    return NULL;
}

void h2_io_set_destroy_all(h2_io_set *sp)
{
    int i;
Loading