Beispiel #1
0
static void io_destroy(h2_mplx *m, h2_io *io, int events)
{
    apr_pool_t *pool = io->pool;
    
    /* cleanup any buffered input */
    h2_io_in_shutdown(io);
    if (events) {
        /* Process outstanding events before destruction */
        io_process_events(m, io);
    }
    
    io->pool = NULL;    
    /* The pool is cleared/destroyed which also closes all
     * allocated file handles. Give this count back to our
     * file handle pool. */
    m->tx_handles_reserved += io->files_handles_owned;

    h2_io_set_remove(m->stream_ios, io);
    h2_io_set_remove(m->ready_ios, io);
    h2_io_destroy(io);
    
    if (pool) {
        apr_pool_clear(pool);
        if (m->spare_pool) {
            apr_pool_destroy(m->spare_pool);
        }
        m->spare_pool = pool;
    }

    check_tx_free(m);
}
Beispiel #2
0
static void io_destroy(h2_mplx *m, h2_io *io, int events)
{
    int reuse_slave;
    
    /* cleanup any buffered input */
    h2_io_in_shutdown(io);
    if (events) {
        /* Process outstanding events before destruction */
        io_in_consumed_signal(m, io);
    }
    
    /* The pool is cleared/destroyed which also closes all
     * allocated file handles. Give this count back to our
     * file handle pool. */
    m->tx_handles_reserved += io->files_handles_owned;

    h2_io_set_remove(m->stream_ios, io);
    h2_io_set_remove(m->ready_ios, io);
    if (m->redo_ios) {
        h2_io_set_remove(m->redo_ios, io);
    }

    reuse_slave = ((m->spare_slaves->nelts < m->spare_slaves->nalloc)
                    && !io->rst_error && io->eor);
    if (io->task) {
        conn_rec *slave = io->task->c;
        h2_task_destroy(io->task);
        io->task = NULL;
        
        if (reuse_slave && slave->keepalive == AP_CONN_KEEPALIVE) {
            apr_bucket_delete(io->eor);
            io->eor = NULL;
            APR_ARRAY_PUSH(m->spare_slaves, conn_rec*) = slave;
        }
Beispiel #3
0
h2_stream *h2_mplx_next_submit(h2_mplx *m, h2_stream_set *streams)
{
    apr_status_t status;
    h2_stream *stream = NULL;
    AP_DEBUG_ASSERT(m);
    if (m->aborted) {
        return NULL;
    }
    status = apr_thread_mutex_lock(m->lock);
    if (APR_SUCCESS == status) {
        h2_io *io = h2_io_set_get_highest_prio(m->ready_ios);
        if (io) {
            h2_response *response = io->response;
            h2_io_set_remove(m->ready_ios, io);
            
            stream = h2_stream_set_get(streams, response->stream_id);
            if (stream) {
                h2_stream_set_response(stream, response, io->bbout);
                if (io->output_drained) {
                    apr_thread_cond_signal(io->output_drained);
                }
            }
            else {
                ap_log_cerror(APLOG_MARK, APLOG_WARNING, APR_NOTFOUND, m->c,
                              APLOGNO(02953) "h2_mplx(%ld): stream for response %d",
                              m->id, response->stream_id);
            }
        }
        apr_thread_mutex_unlock(m->lock);
    }
    return stream;
}
Beispiel #4
0
static int io_stream_done(h2_mplx *m, h2_io *io, int rst_error) 
{
    /* Remove io from ready set, we will never submit it */
    h2_io_set_remove(m->ready_ios, io);
    if (!io->worker_started || io->worker_done) {
        /* already finished or not even started yet */
        h2_tq_remove(m->q, io->id);
        io_destroy(m, io, 1);
        return 0;
    }
    else {
        /* cleanup once task is done */
        h2_io_make_orphaned(io, rst_error);
        return 1;
    }
}
Beispiel #5
0
static int io_stream_done(h2_mplx *m, h2_io *io, int rst_error) 
{
    /* Remove io from ready set, we will never submit it */
    h2_io_set_remove(m->ready_ios, io);
    if (io->task_done || h2_tq_remove(m->q, io->id)) {
        /* already finished or not even started yet */
        io_destroy(m, io, 1);
        return 0;
    }
    else {
        /* cleanup once task is done */
        io->orphaned = 1;
        if (rst_error) {
            h2_io_rst(io, rst_error);
        }
        return 1;
    }
}
Beispiel #6
0
static void stream_destroy(h2_mplx *m, h2_stream *stream, h2_io *io)
{
    apr_pool_t *pool = h2_stream_detach_pool(stream);
    if (pool) {
        apr_pool_clear(pool);
        if (m->spare_pool) {
            apr_pool_destroy(m->spare_pool);
        }
        m->spare_pool = pool;
    }
    h2_stream_destroy(stream);
    if (io) {
        /* The pool is cleared/destroyed which also closes all
         * allocated file handles. Give this count back to our
         * file handle pool. */
        m->file_handles_allowed += io->files_handles_owned;
        h2_io_set_remove(m->stream_ios, io);
        h2_io_destroy(io);
    }
}