static void 
ngx_rtmp_exec_child_dead(ngx_event_t *ev)
{
    ngx_connection_t   *dummy_conn = ev->data;
    ngx_rtmp_exec_t    *e;

    e = dummy_conn->data;

    ngx_log_debug2(NGX_LOG_DEBUG_RTMP, e->log, 0,
                   "exec: child %ui exited; %s", (ngx_int_t) e->pid,
                   e->respawn_timeout == NGX_CONF_UNSET_MSEC ? "respawning" :
                                                               "ignoring");

    ngx_rtmp_exec_kill(e, 0);

    if (e->respawn_timeout == NGX_CONF_UNSET_MSEC) {
        return;
    }

    if (e->respawn_timeout == 0) {
        ngx_rtmp_exec_run(e);
        return;
    }

    ngx_log_debug1(NGX_LOG_DEBUG_RTMP, e->log, 0,
                   "exec: shedule respawn %Mmsec", e->respawn_timeout);

    e->respawn_evt.data = e;
    e->respawn_evt.log = e->log;
    e->respawn_evt.handler = ngx_rtmp_exec_respawn;

    ngx_add_timer(&e->respawn_evt, e->respawn_timeout);
}
static ngx_int_t
ngx_rtmp_exec_close_stream(ngx_rtmp_session_t *s, ngx_rtmp_close_stream_t *v)
{
    ngx_rtmp_exec_app_conf_t       *eacf;
    ngx_rtmp_exec_ctx_t            *ctx;
    ngx_rtmp_exec_t                *e;
    size_t                          n;

    eacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_exec_module);
    if (eacf == NULL) {
        goto next;
    }

    ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_exec_module);
    if (ctx == NULL || ctx->execs.nelts == 0) {
        goto next;
    }

    ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
                   "exec: delete %uz command(s)", ctx->execs.nelts);

    e = ctx->execs.elts;
    for (n = 0; n < ctx->execs.nelts; ++n, ++e) {
        ngx_rtmp_exec_kill(e, e->kill_signal);
    }

next:
    return next_close_stream(s, v);
}
static void 
ngx_rtmp_exec_child_dead(ngx_event_t *ev)
{
    ngx_connection_t               *dummy_conn;
    ngx_rtmp_exec_t                *e;
    ngx_rtmp_session_t             *s;
    ngx_rtmp_exec_app_conf_t       *eacf;

    dummy_conn = ev->data;
    e = dummy_conn->data;
    s = e->session;
    eacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_exec_module);

    ngx_log_debug2(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
            "exec: child %ui exited; %s", 
            (ngx_int_t)e->pid,
            eacf->respawn ? "respawning" : "ignoring");

    ngx_rtmp_exec_kill(s, e, 0);

    if (!eacf->respawn) {
        return;
    }

    if (eacf->respawn_timeout == 0) {
        ngx_rtmp_exec_run(s, e->index);
        return;
    }

    ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
            "exec: shedule respawn %Mmsec", eacf->respawn_timeout);
    e->respawn_evt.data = e;
    e->respawn_evt.log = s->connection->log;
    e->respawn_evt.handler = ngx_rtmp_exec_respawn;
    ngx_add_timer(&e->respawn_evt, eacf->respawn_timeout);
}