示例#1
0
  void ObjectMemory::run_finalizers(STATE, CallFrame* call_frame) {
    if(running_finalizers_) return;
    running_finalizers_ = true;

    for(std::list<FinalizeObject*>::iterator i = to_finalize_.begin();
        i != to_finalize_.end(); ) {
      FinalizeObject* fi = *i;

      if(fi->finalizer) {
        (*fi->finalizer)(state, fi->object);
        // Unhook any handle used by fi->object so that we don't accidentally
        // try and mark it later (after we've finalized it)
        if(fi->object->inflated_header_p()) {
          InflatedHeader* ih = fi->object->inflated_header();

          if(capi::Handle* handle = ih->handle()) {
            handle->forget_object();
            ih->set_handle(0);
          }
        }

        // If the object was remembered, unremember it.
        if(fi->object->remembered_p()) {
          unremember_object(fi->object);
        }
      } else if(fi->ruby_finalizer) {
        // Rubinius specific code. If the finalizer is Qtrue, then
        // send the object the finalize message
        if(fi->ruby_finalizer == Qtrue) {
          fi->object->send(state, call_frame, state->symbol("__finalize__"), true);
        } else {
          Array* ary = Array::create(state, 1);
          ary->set(state, 0, fi->object->id(state));

          OnStack<1> os(state, ary);

          fi->ruby_finalizer->send(state, call_frame, state->symbol("call"), ary, Qnil, true);
        }
      } else {
        std::cerr << "Unsupported object to be finalized: "
                  << fi->object->to_s(state)->c_str() << "\n";
      }

      fi->status = FinalizeObject::eFinalized;

      i = to_finalize_.erase(i);
    }

    running_finalizers_ = false;
  }
示例#2
0
  void ObjectMemory::in_finalizer_thread(STATE) {
    CallFrame* call_frame = 0;
    utilities::thread::Thread::set_os_name("rbx.finalizer");

    GCTokenImpl gct;
    state->vm()->thread->hard_unlock(state, gct);

    // Forever
    for(;;) {
      FinalizeObject* fi;

      // Take the lock, remove the first one from the list,
      // then process it.
      {
        SCOPE_LOCK(state->vm(), finalizer_lock_);

        state->vm()->set_call_frame(0);

        while(to_finalize_.empty()) {
          GCIndependent indy(state);
          finalizer_var_.wait(finalizer_lock_);
        }

        fi = to_finalize_.front();
        to_finalize_.pop_front();
      }

      if(fi->finalizer) {
        (*fi->finalizer)(state, fi->object);
        // Unhook any handle used by fi->object so that we don't accidentally
        // try and mark it later (after we've finalized it)
        if(capi::Handle* handle = fi->object->handle(state)) {
          handle->forget_object();
          fi->object->clear_handle(state);
        }

        // If the object was remembered, unremember it.
        if(fi->object->remembered_p()) {
          unremember_object(fi->object);
        }
      } else if(fi->ruby_finalizer) {
        // Rubinius specific code. If the finalizer is cTrue, then
        // send the object the finalize message
        if(fi->ruby_finalizer == cTrue) {
          fi->object->send(state, call_frame, state->symbol("__finalize__"));
        } else {
          Array* ary = Array::create(state, 1);
          ary->set(state, 0, fi->object->id(state));

          OnStack<1> os(state, ary);

          fi->ruby_finalizer->send(state, call_frame, G(sym_call), ary);
        }
      } else {
        std::cerr << "Unsupported object to be finalized: "
                  << fi->object->to_s(state)->c_str(state) << std::endl;
      }

      fi->status = FinalizeObject::eFinalized;
    }

    state->checkpoint(gct, 0);
  }