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); }
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; }
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; }
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; } }
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; } }
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); } }