Example #1
0
static VALUE
rb_cont_call(int argc, VALUE *argv, VALUE contval)
{
    rb_context_t *cont;
    rb_thread_t *th = GET_THREAD();
    GetContPtr(contval, cont);

    if (cont->saved_thread.self != th->self) {
	rb_raise(rb_eRuntimeError, "continuation called across threads");
    }
    if (cont->saved_thread.trap_tag != th->trap_tag) {
	rb_raise(rb_eRuntimeError, "continuation called across trap");
    }
    if (cont->saved_thread.fiber) {
	rb_context_t *fcont;
	GetContPtr(cont->saved_thread.fiber, fcont);

	if (th->fiber != cont->saved_thread.fiber) {
	    rb_raise(rb_eRuntimeError, "continuation called across fiber");
	}
    }

    cont->argc = argc;
    cont->value = make_passing_arg(argc, argv);

    cont_restore_0(cont, &contval);
    return Qnil; /* unreachable */
}
Example #2
0
File: cont.c Project: genki/ruby
static inline VALUE
fiber_switch(VALUE fib, int argc, VALUE *argv, int is_resume)
{
    VALUE value;
    rb_context_t *cont;
    rb_thread_t *th = GET_THREAD();

    GetContPtr(fib, cont);

    if (cont->saved_thread.self != th->self) {
	rb_raise(rb_eFiberError, "fiber called across threads");
    }
    else if (cont->saved_thread.trap_tag != th->trap_tag) {
	rb_raise(rb_eFiberError, "fiber called across trap");
    }
    else if (!cont->alive) {
	rb_raise(rb_eFiberError, "dead fiber called");
    }

    if (is_resume) {
	cont->prev = rb_fiber_current();
    }

    cont->value = make_passing_arg(argc, argv);

    if ((value = fiber_store(cont)) == Qundef) {
	cont_restore_0(cont, &value);
	rb_bug("rb_fiber_resume: unreachable");
    }

    RUBY_VM_CHECK_INTS();

    return value;
}