Esempio n. 1
0
  void Fiber::start_on_stack() {
#ifdef FIBER_ENABLED
    VM* state = VM::current();

    Fiber* fib = Fiber::current(state);

    // Affix this fiber to this thread now.
    fib->state_ = state;

    fib->starter()->send(state, NULL, G(sym_call));
    // GC has run! Don't use stack vars!

    fib = Fiber::current(state);
    fib->status_ = Fiber::eDead;

    Fiber* dest = fib->prev();
    assert(!dest->nil_p());

    dest->run();
    dest->value(state, Qnil);
    state->set_current_fiber(dest);

    if(setcontext(dest->ucontext()) != 0)
      assert(0 && "fatal swapcontext() error");

    assert(0 && "fatal start_on_stack error");
#else
    abort();
#endif
  }
Esempio n. 2
0
  void Fiber::start_on_stack() {
#ifdef RBX_FIBER_ENABLED
    VM* vm = VM::current();
    State state_obj(vm), *state = &state_obj;

    Fiber* fib = Fiber::current(state);

    // Reset the current fiber again to reset the stack limits so
    // we can properly detect stack overflows
    vm->set_current_fiber(fib);

    Array* result = nil<Array>();
    Object* obj = fib->starter()->send(state, G(sym_call), fib->value(), cNil, false);

    // GC has run! Don't use stack vars!

    fib = Fiber::current(state);
    fib->status(Fiber::eDead);
    fib->dead(cTrue);
    fib->set_call_frame(state, 0);

    Fiber* dest = fib->prev();

    // If this fiber has already been cleaned up, just ignore this
    if(!dest->data()) return;

    assert(!dest->nil_p());

    // Box this up so it's in a standard format at the point
    // of returning, so we can deal with it in the same way
    // as *args from #yield, #resume, and #transfer
    if(obj) {
      result = Array::create(state, 1);
      result->set(state, 0, obj);
    } else {
      if(state->vm()->thread_state()->raise_reason() == cException) {
        dest->exception(state, state->vm()->thread_state()->current_exception());
      }
    }

    vm->metrics().system.fibers_destroyed++;

    dest->run(state);
    dest->value(state, result);

    dest->data()->switch_and_orphan(state, fib->data());

    // TODO: CallFrame: return from this function

    rubinius::bug("returning from Fiber::start_on_stack");
#else
    rubinius::bug("Fibers not supported on this platform");
#endif
  }
Esempio n. 3
0
  void Fiber::start_on_stack() {
#ifdef RBX_FIBER_ENABLED
    VM* vm = VM::current();
    State state(vm);

    Fiber* fib = Fiber::current(&state);

    // Reset the current fiber again to reset the stack limits so
    // we can properly detect stack overflows
    vm->set_current_fiber(fib);

    Array* result = nil<Array>();
    Object* obj = fib->starter()->send(&state, NULL, state.globals().sym_call.get(), fib->value(), cNil, false);
    // GC has run! Don't use stack vars!

    fib = Fiber::current(&state);
    fib->status_ = Fiber::eDead;
    fib->dead_ = cTrue;

    Fiber* dest = fib->prev();

    // If this fiber has already been cleaned up, just ignore this
    if(!dest->data()) return;

    assert(!dest->nil_p());

    // Box this up so it's in a standard format at the point
    // of returning, so we can deal with it in the same way
    // as *args from #yield, #resume, and #transfer
    if(obj) {
      result = Array::create(&state, 1);
      result->set(&state, 0, obj);
    } else {
      if(state.vm()->thread_state()->raise_reason() == cException) {
        dest->exception(&state, state.vm()->thread_state()->current_exception());
      }
    }

    dest->run();
    dest->value(&state, result);
    state.vm()->set_current_fiber(dest);

    dest->data_->switch_and_orphan(&state, fib->data_);

    assert(0 && "fatal start_on_stack error");
#else
    rubinius::bug("Fibers not supported on this platform");
#endif
  }
Esempio n. 4
0
  void Fiber::start_on_stack() {
#ifdef FIBER_ENABLED
    VM* state = VM::current();

    Fiber* fib = Fiber::current(state);

    // Affix this fiber to this thread now.
    fib->state_ = state;

    Array* result = (Array*)Qnil;
    Object* obj = fib->starter()->send(state, NULL, G(sym_call), fib->value(), Qnil, false);
    // GC has run! Don't use stack vars!

    fib = Fiber::current(state);
    fib->status_ = Fiber::eDead;
    fib->set_ivar(state, state->symbol("@dead"), Qtrue);

    Fiber* dest = fib->prev();
    assert(!dest->nil_p());

    // Box this up so it's in a standard format at the point
    // of returning, so we can deal with it in the same way
    // as *args from #yield, #resume, and #transfer
    if(obj) {
      result = Array::create(state, 1);
      result->set(state, 0, obj);
    } else {
      if(state->thread_state()->raise_reason() == cException) {
        dest->exception(state, state->thread_state()->current_exception());
      }
    }

    dest->run();
    dest->value(state, result);
    state->set_current_fiber(dest);

    if(setcontext(dest->ucontext()) != 0)
      assert(0 && "fatal swapcontext() error");

    assert(0 && "fatal start_on_stack error");
#else
    abort();
#endif
  }