示例#1
0
/** Runs the VM finalization processes.
 *
 * <code>END{}</code> and procs registered by <code>Kernel.#at_exit</code> are
 * executed here. See the Ruby language spec for more details.
 *
 * @note This function is allowed to raise an exception if an error occurred.
 */
void
ruby_finalize(void)
{
    ruby_finalize_0();
    ruby_finalize_1();
}
示例#2
0
int
ruby_cleanup(int ex)
{
    int state;
    volatile VALUE errs[2];
    rb_thread_t *th = GET_THREAD();
    int nerr;

    errs[1] = th->errinfo;
    th->safe_level = 0;
    Init_stack((void*)&errs[STACK_UPPER(errs, 0, 1)]);

    PUSH_TAG();
    if ((state = EXEC_TAG()) == 0) {
        SAVE_ROOT_JMPBUF(th, ruby_finalize_0());
    }
    POP_TAG();

    errs[0] = th->errinfo;
    PUSH_TAG();
    if ((state = EXEC_TAG()) == 0) {
        SAVE_ROOT_JMPBUF(th, rb_thread_terminate_all());
    }
    else if (ex == 0) {
        ex = state;
    }
    th->errinfo = errs[1];
    ex = error_handle(ex);
    ruby_finalize_1();
    POP_TAG();
    rb_thread_stop_timer_thread();

    for (nerr = 0; nerr < sizeof(errs) / sizeof(errs[0]); ++nerr) {
        VALUE err = errs[nerr];

        if (!RTEST(err)) continue;

        /* th->errinfo contains a NODE while break'ing */
        if (TYPE(err) == T_NODE) continue;

        if (rb_obj_is_kind_of(err, rb_eSystemExit)) {
            return sysexit_status(err);
        }
        else if (rb_obj_is_kind_of(err, rb_eSignal)) {
            VALUE sig = rb_iv_get(err, "signo");
            ruby_default_signal(NUM2INT(sig));
        }
        else if (ex == 0) {
            ex = 1;
        }
    }

#if EXIT_SUCCESS != 0 || EXIT_FAILURE != 1
    switch (ex) {
#if EXIT_SUCCESS != 0
    case 0:
        return EXIT_SUCCESS;
#endif
#if EXIT_FAILURE != 1
    case 1:
        return EXIT_FAILURE;
#endif
    }
#endif

    return ex;
}