MP_TRACE_h(MP_FUNC, "running %d %s handlers\n", nelts, desc);
MP_TRACE_h(MP_FUNC, "[%s] running %d %s handlers\n", modperl_pid_tid(p), nelts, desc);
int modperl_callback_run_handlers(int idx, int type,                                  request_rec *r, conn_rec *c, server_rec *s,                                  apr_pool_t *pconf,                                  apr_pool_t *plog,                                  apr_pool_t *ptemp,                                  modperl_hook_run_mode_e run_mode){#ifdef USE_ITHREADS    pTHX;    modperl_interp_t *interp = NULL;#endif    MP_dSCFG(s);    MP_dDCFG;    MP_dRCFG;    modperl_handler_t **handlers;    apr_pool_t *p = NULL;    MpAV *av, **avp;    int i, nelts, status = OK;    const char *desc = NULL;    AV *av_args = Nullav;    if (!MpSrvENABLE(scfg)) {        MP_TRACE_h(MP_FUNC, "PerlOff for server %s\n",                   s->server_hostname);        return DECLINED;    }    if (r || c) {        p = c ? c->pool : r->pool;    }    else {        p = pconf;    }    avp = modperl_handler_lookup_handlers(dcfg, scfg, rcfg, p,                                          type, idx, FALSE, &desc);    if (!(avp && (av = *avp))) {        MP_TRACE_h(MP_FUNC, "no %s handlers configured (%s)\n",                   desc, r ? r->uri : "");        return DECLINED;    }#ifdef USE_ITHREADS    if (r && !c && modperl_interp_scope_connection(scfg)) {        c = r->connection;    }    if (r || c) {        interp = modperl_interp_select(r, c, s);        aTHX = interp->perl;    }    else {        /* Child{Init,Exit}, OpenLogs */        aTHX = scfg->mip->parent->perl;        PERL_SET_CONTEXT(aTHX);    }#endif    /* XXX: would like to do this in modperl_hook_create_request()     * but modperl_interp_select() is what figures out if     * PerlInterpScope eq handler, in which case we do not register     * a cleanup.  modperl_hook_create_request() is also currently always     * run even if modperl isn't handling any part of the request     */    modperl_config_req_cleanup_register(r, rcfg);    switch (type) {      case MP_HANDLER_TYPE_PER_DIR:      case MP_HANDLER_TYPE_PER_SRV:        modperl_handler_make_args(aTHX_ &av_args,                                  "Apache::RequestRec", r, NULL);        /* only happens once per-request */        if (MpDirSETUP_ENV(dcfg)) {            modperl_env_request_populate(aTHX_ r);        }        break;      case MP_HANDLER_TYPE_PRE_CONNECTION:      case MP_HANDLER_TYPE_CONNECTION:        modperl_handler_make_args(aTHX_ &av_args,                                  "Apache::Connection", c, NULL);        break;      case MP_HANDLER_TYPE_FILES:        modperl_handler_make_args(aTHX_ &av_args,                                  "Apache::Pool", pconf,                                  "Apache::Pool", plog,                                  "Apache::Pool", ptemp,                                  "Apache::Server", s, NULL);        break;      case MP_HANDLER_TYPE_PROCESS:        modperl_handler_make_args(aTHX_ &av_args,                                  "Apache::Pool", pconf,                                  "Apache::Server", s, NULL);        break;    };    modperl_callback_current_callback_set(desc);        /* XXX: deal with {push,set}_handler of the phase we're currently in */    /* for now avoid the segfault by not letting av->nelts grow if     * somebody push_handlers to the phase we are currently in, but     * different handler e.g. jumping from 'modperl' to 'perl-script',     * before calling push_handler */    nelts = av->nelts;    MP_TRACE_h(MP_FUNC, "running %d %s handlers\n", nelts, desc);    handlers = (modperl_handler_t **)av->elts;    for (i=0; i<nelts; i++) {        status = modperl_callback(aTHX_ handlers[i], p, r, s, av_args);                MP_TRACE_h(MP_FUNC, "%s returned %d\n", handlers[i]->name, status);        /* follow Apache's lead and let OK terminate the phase for         * MP_HOOK_RUN_FIRST handlers.  MP_HOOK_RUN_ALL handlers keep going on OK.         * MP_HOOK_VOID handler ignore all errors.         */        if (run_mode == MP_HOOK_RUN_ALL) {            /* the normal case:             *   OK and DECLINED continue              *   errors end the phase             */            if ((status != OK) && (status != DECLINED)) {                status = modperl_errsv(aTHX_ status, r, s);#ifdef MP_TRACE                if (i+1 != nelts) {                    MP_TRACE_h(MP_FUNC, "error status %d leaves %d uncalled handlers\n",                               status, desc, nelts-i-1);                }#endif                break;            }        }        else if (run_mode == MP_HOOK_RUN_FIRST) {            /* the exceptional case:             *   OK and errors end the phase             *   DECLINED continues             */            if (status == OK) {#ifdef MP_TRACE                if (i+1 != nelts) {                    MP_TRACE_h(MP_FUNC, "OK ends the %s stack, leaving %d uncalled handlers\n",                               desc, nelts-i-1);                }#endif                break;            }            if (status != DECLINED) {                status = modperl_errsv(aTHX_ status, r, s);#ifdef MP_TRACE                if (i+1 != nelts) {                    MP_TRACE_h(MP_FUNC, "error status %d leaves %d uncalled handlers\n",                               status, desc, nelts-i-1);                }#endif                break;            }        }        else {            /* the rare case.             * MP_HOOK_VOID handlers completely ignore the return status             * Apache should handle whatever mod_perl returns,              * so there is no need to mess with the status             */        }    }    SvREFCNT_dec((SV*)av_args);#ifdef USE_ITHREADS    MP_dINTERP_PUTBACK(interp);#endif    return status;}