void FinalizerHandler::perform(STATE) { GCTokenImpl gct; utilities::thread::Thread::set_os_name("rbx.finalizer"); state->vm()->thread->hard_unlock(state, gct); while(!exit_) { if(!process_list_) first_process_item(); if(!process_list_) { utilities::thread::Mutex::LockGuard lg(worker_lock_); if(finishing_) supervisor_signal(); // exit_ might have been set in the mean while after // we grabbed the worker_lock if(!exit_) { GCIndependent indy(state); worker_wait(); } continue; } finalize(state); next_process_item(); } }
void FinalizerHandler::finish(STATE, GCToken gct) { if(!self_) { if(process_list_ || !lists_->empty() || !live_list_->empty()) { rubinius::bug("FinalizerHandler worker thread dead during halt"); } else { return; } } finishing_ = true; while(true) { { StopTheWorld stw(state, gct, 0); if(!process_list_) { if(live_list_->empty() && lists_->empty()) break; // Everything is garbage when halting so keep adding live objects to // finalize queue until done. if(!live_list_->empty()) { for(FinalizeObjects::iterator i = live_list_->begin(); i != live_list_->end(); ++i) { i->queued(); } queue_objects(); } first_process_item(); if(!process_list_) break; } } worker_signal(); { utilities::thread::Mutex::LockGuard lg(supervisor_lock_); state->vm()->set_call_frame(0); GCIndependent indy(state); if(process_list_) supervisor_wait(); } } if(!lists_->empty() || !live_list_->empty() || process_list_ != NULL) rubinius::bug("FinalizerHandler exiting with pending finalizers"); stop_thread(state); }
void FinalizerHandler::perform(STATE) { GCTokenImpl gct; const char* thread_name = "rbx.finalizer"; self_->set_name(thread_name); RUBINIUS_THREAD_START(thread_name, state->vm()->thread_id(), 1); state->vm()->thread->hard_unlock(state, gct, 0); while(!exit_) { state->vm()->set_call_frame(0); if(!process_list_) first_process_item(); if(!process_list_) { { utilities::thread::Mutex::LockGuard lg(worker_lock_); if(finishing_) supervisor_signal(); // exit_ might have been set in the mean while after // we grabbed the worker_lock if(exit_) break; state->gc_independent(gct, 0); paused_ = true; pause_cond_.signal(); worker_wait(); if(exit_) break; } state->gc_dependent(); { utilities::thread::Mutex::LockGuard lg(worker_lock_); paused_ = false; if(exit_) break; } continue; } finalize(state); next_process_item(); } RUBINIUS_THREAD_STOP(thread_name, state->vm()->thread_id(), 1); }