Beispiel #1
0
static int
exec_hooks_precheck(rb_thread_t *th, rb_hook_list_t *list, const rb_trace_arg_t *trace_arg)
{
    if ((list->events & trace_arg->event) == 0) return 0;

    if (UNLIKELY(list->need_clean > 0)) {
        if (th->vm->trace_running <= 1) { /* only running this hooks */
            clean_hooks(list);
        }
    }
    return 1;
}
Beispiel #2
0
static int
exec_hooks(rb_thread_t *th, rb_hook_list_t *list, const rb_trace_arg_t *trace_arg, int can_clean_hooks)
{
    int state;
    volatile int raised;

    if (UNLIKELY(list->need_clean > 0) && can_clean_hooks) {
	clean_hooks(list);
    }

    raised = rb_threadptr_reset_raised(th);

    /* TODO: Support !RUBY_EVENT_HOOK_FLAG_SAFE hooks */

    TH_PUSH_TAG(th);
    if ((state = TH_EXEC_TAG()) == 0) {
	rb_event_hook_t *hook;

	for (hook = list->hooks; hook; hook = hook->next) {
	    if (LIKELY(!(hook->hook_flags & RUBY_EVENT_HOOK_FLAG_DELETED)) && (trace_arg->event & hook->events)) {
		if (!(hook->hook_flags & RUBY_EVENT_HOOK_FLAG_RAW_ARG)) {
		    (*hook->func)(trace_arg->event, hook->data, trace_arg->self, trace_arg->id, trace_arg->klass);
		}
		else {
		    (*((rb_event_hook_raw_arg_func_t)hook->func))(hook->data, trace_arg);
		}
	    }
	}
    }
    TH_POP_TAG();

    if (raised) {
	rb_threadptr_set_raised(th);
    }

    return state;
}