Object* Fiber::s_yield(STATE, Arguments& args) { Fiber* fiber = state->vm()->fiber(); OnStack<1> os(state, fiber); { std::lock_guard<std::mutex> guard(state->vm()->thread()->fiber_mutex()); if(fiber->root_p()) { Exception::raise_fiber_error(state, "can't yield from root fiber"); } else if(fiber->status() == eTransfer) { Exception::raise_fiber_error(state, "can't yield from transferred fiber"); } fiber->unpack_arguments(state, args); fiber->status(eYielding); } // Being cooperative... fiber->invoke_context()->fiber()->restart(state); // Through the worm hole... fiber->suspend_and_continue(state); // We're back... return fiber->return_value(state); }
/* This creates the pseudo-Fiber for the Thread. This provides a uniform * means of expressing things like Fiber.current. */ Fiber* Fiber::create(STATE, VM* vm) { Fiber* fiber = state->memory()->new_object_pinned<Fiber>(state, G(fiber)); vm->set_fiber(fiber); vm->set_running(); fiber->vm(vm); fiber->pid(vm->thread()->pid()); fiber->stack_size(vm->thread()->stack_size()); fiber->thread_name(state, String::create(state, vm->name().c_str())); fiber->fiber_id(Fixnum::from(0)); fiber->status(eRunning); fiber->invoke_context(vm); return fiber; }