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

On the trunk:

  *) mod_http2: stream timeouts now change to vhost values once the request
     is parsed and processing starts. Initial values are taken from base
     server or SNI host as before. 



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1785683 13f79535-47bb-0310-9956-ffa450edef68
parent dda1c739
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
                                                         -*- coding: utf-8 -*-
Changes with Apache 2.5.0

  *) mod_http2: stream timeouts now change to vhost values once the request
     is parsed and processing starts. Initial values are taken from base
     server or SNI host as before. [Stefan Eissing]
     
  *) mod_proxy_http2: fixed retry behaviour when frontend connection uses 
     http/1.1. [Stefan Eissing]
     
+8 −1
Original line number Diff line number Diff line
@@ -559,7 +559,8 @@ apr_status_t h2_beam_destroy(h2_bucket_beam *beam)
apr_status_t h2_beam_create(h2_bucket_beam **pbeam, apr_pool_t *pool, 
                            int id, const char *tag, 
                            h2_beam_owner_t owner,
                            apr_size_t max_buf_size)
                            apr_size_t max_buf_size,
                            apr_interval_time_t timeout)
{
    h2_bucket_beam *beam;
    apr_status_t status = APR_SUCCESS;
@@ -579,6 +580,7 @@ apr_status_t h2_beam_create(h2_bucket_beam **pbeam, apr_pool_t *pool,
    H2_BPROXY_LIST_INIT(&beam->proxies);
    beam->tx_mem_limits = 1;
    beam->max_buf_size = max_buf_size;
    beam->timeout = timeout;

    status = apr_thread_mutex_create(&beam->lock, APR_THREAD_MUTEX_DEFAULT, 
                                     pool);
@@ -978,6 +980,11 @@ transfer:
                                                    bb->p, bb->bucket_alloc);
                }
            }
            else if (bsender->length == 0) {
                APR_BUCKET_REMOVE(bsender);
                H2_BLIST_INSERT_TAIL(&beam->hold_list, bsender);
                continue;
            }
            else if (APR_BUCKET_IS_FILE(bsender)) {
                /* This is set aside into the target brigade pool so that 
                 * any read operation messes with that pool and not 
+3 −1
Original line number Diff line number Diff line
@@ -223,12 +223,14 @@ struct h2_bucket_beam {
 *                      the pool owner is using this beam for sending or receiving
 * @param buffer_size   maximum memory footprint of buckets buffered in beam, or
 *                      0 for no limitation
 * @param timeout       timeout for blocking operations
 */
apr_status_t h2_beam_create(h2_bucket_beam **pbeam,
                            apr_pool_t *pool, 
                            int id, const char *tag,
                            h2_beam_owner_t owner,  
                            apr_size_t buffer_size);
                            apr_size_t buffer_size,
                            apr_interval_time_t timeout);

/**
 * Destroys the beam immediately without cleanup.
+15 −34
Original line number Diff line number Diff line
@@ -100,6 +100,8 @@ static void leave_mutex(h2_mplx *m, int acquired)
    }
}

static void check_data_for(h2_mplx *m, int stream_id);

static void stream_output_consumed(void *ctx, 
                                   h2_bucket_beam *beam, apr_off_t length)
{
@@ -154,8 +156,6 @@ static int can_beam_file(void *ctx, h2_bucket_beam *beam, apr_file_t *file)
    return 0;
}

static void have_out_data_for(h2_mplx *m, h2_stream *stream);

static void check_tx_reservation(h2_mplx *m) 
{
    if (m->tx_handles_reserved <= 0) {
@@ -228,7 +228,6 @@ static void stream_cleanup(h2_mplx *m, h2_stream *stream)
 */
h2_mplx *h2_mplx_create(conn_rec *c, apr_pool_t *parent, 
                        const h2_config *conf, 
                        apr_interval_time_t stream_timeout,
                        h2_workers *workers)
{
    apr_status_t status = APR_SUCCESS;
@@ -292,7 +291,6 @@ h2_mplx *h2_mplx_create(conn_rec *c, apr_pool_t *parent,
        m->q = h2_iq_create(m->pool, m->max_streams);
        m->readyq = h2_iq_create(m->pool, m->max_streams);

        m->stream_timeout = stream_timeout;
        m->workers = workers;
        m->workers_max = workers->max_workers;
        m->workers_limit = 6; /* the original h1 max parallel connections */
@@ -581,17 +579,12 @@ void h2_mplx_set_consumed_cb(h2_mplx *m, h2_mplx_consumed_cb *cb, void *ctx)
static void output_produced(void *ctx, h2_bucket_beam *beam, apr_off_t bytes)
{
    h2_mplx *m = ctx;
    apr_status_t status;
    h2_stream *stream;
    int acquired;
    
    if ((status = enter_mutex(m, &acquired)) == APR_SUCCESS) {
        stream = h2_ihash_get(m->streams, beam->id);
        if (stream) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, status, m->c,
                          "h2_mplx(%s): output_produced", stream->task->id);
            have_out_data_for(m, stream);
        }
    if (enter_mutex(m, &acquired) == APR_SUCCESS) {
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c,
                      "h2_mplx(%ld-%d): output_produced", m->c->id, beam->id);
        check_data_for(m, beam->id);
        leave_mutex(m, acquired);
    }
}
@@ -633,7 +626,7 @@ static apr_status_t out_open(h2_mplx *m, int stream_id, h2_bucket_beam *beam)
    /* we might see some file buckets in the output, see
     * if we have enough handles reserved. */
    check_tx_reservation(m);
    have_out_data_for(m, stream);
    check_data_for(m, stream->id);
    return status;
}

@@ -673,7 +666,7 @@ static apr_status_t out_close(h2_mplx *m, h2_task *task)
    status = h2_beam_close(task->output.beam);
    h2_beam_log(task->output.beam, m->c, APLOG_TRACE2, "out_close");
    output_consumed_signal(m, task);
    have_out_data_for(m, stream);
    check_data_for(m, task->stream_id);
    return status;
}

@@ -706,11 +699,10 @@ apr_status_t h2_mplx_out_trywait(h2_mplx *m, apr_interval_time_t timeout,
    return status;
}

static void have_out_data_for(h2_mplx *m, h2_stream *stream)
static void check_data_for(h2_mplx *m, int stream_id)
{
    ap_assert(m);
    ap_assert(stream);
    h2_iq_append(m->readyq, stream->id);
    h2_iq_append(m->readyq, stream_id);
    apr_atomic_set32(&m->event_pending, 1);
    if (m->added_output) {
        apr_thread_cond_signal(m->added_output);
@@ -751,8 +743,7 @@ apr_status_t h2_mplx_process(h2_mplx *m, struct h2_stream *stream,
            h2_ihash_add(m->streams, stream);
            if (h2_stream_is_ready(stream)) {
                /* already have a response */
                apr_atomic_set32(&m->event_pending, 1);
                h2_iq_append(m->readyq, stream->id);
                check_data_for(m, stream->id);
                ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, m->c,
                              H2_STRM_MSG(stream, "process, add to readyq")); 
            }
@@ -813,7 +804,6 @@ static h2_task *next_stream_task(h2_mplx *m)
                }
                
                if (stream->input) {
                    h2_beam_timeout_set(stream->input, m->stream_timeout);
                    h2_beam_on_consumed(stream->input, stream_input_ev, 
                                        stream_input_consumed, m);
                    h2_beam_on_file_beam(stream->input, can_beam_file, m);
@@ -821,7 +811,6 @@ static h2_task *next_stream_task(h2_mplx *m)
                }
                
                h2_beam_buffer_size_set(stream->output, m->stream_max_mem);
                h2_beam_timeout_set(stream->output, m->stream_timeout);
            }
            stream->task->worker_started = 1;
            stream->task->started_at = apr_time_now();
@@ -938,7 +927,7 @@ static void task_done(h2_mplx *m, h2_task *task, h2_req_engine *ngn)
            h2_beam_leave(stream->input);
        }
        h2_beam_mutex_disable(stream->output);
        have_out_data_for(m, stream);
        check_data_for(m, stream->id);
    }
    else if ((stream = h2_ihash_get(m->shold, task->stream_id)) != NULL) {
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c,
@@ -1022,7 +1011,7 @@ static int timed_out_busy_iter(void *data, void *val)
    stream_iter_ctx *ctx = data;
    h2_stream *stream = val;
    if (stream->task && !stream->task->worker_done
        && (ctx->now - stream->task->started_at) > ctx->m->stream_timeout) {
        && (ctx->now - stream->task->started_at) > stream->task->timeout) {
        /* timed out stream occupying a worker, found */
        ctx->stream = stream;
        return 0;
@@ -1279,10 +1268,6 @@ apr_status_t h2_mplx_dispatch_master_events(h2_mplx *m,
    h2_stream *stream;
    size_t i, n;
    
    if (!h2_mplx_has_master_events(m)) {
        return APR_EAGAIN;
    }
    
    if ((status = enter_mutex(m, &acquired)) == APR_SUCCESS) {
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c, 
                      "h2_mplx(%ld): dispatch events", m->id);        
@@ -1314,11 +1299,7 @@ apr_status_t h2_mplx_keep_active(h2_mplx *m, int stream_id)
    int acquired;
    
    if ((status = enter_mutex(m, &acquired)) == APR_SUCCESS) {
        h2_stream *s = h2_ihash_get(m->streams, stream_id);
        if (s) {
            h2_iq_append(m->readyq, stream_id);
            apr_atomic_set32(&m->event_pending, 1);
        }
        check_data_for(m, stream_id);
        leave_mutex(m, acquired);
    }
    return status;
+0 −2
Original line number Diff line number Diff line
@@ -96,7 +96,6 @@ struct h2_mplx {
    struct apr_thread_cond_t *join_wait;
    
    apr_size_t stream_max_mem;
    apr_interval_time_t stream_timeout;
    
    apr_pool_t *spare_io_pool;
    apr_array_header_t *spare_slaves; /* spare slave connections */
@@ -125,7 +124,6 @@ apr_status_t h2_mplx_child_init(apr_pool_t *pool, server_rec *s);
 */
h2_mplx *h2_mplx_create(conn_rec *c, apr_pool_t *master, 
                        const struct h2_config *conf, 
                        apr_interval_time_t stream_timeout,
                        struct h2_workers *workers);

/**
Loading