bool VM::wakeup(STATE) { utilities::thread::SpinLock::LockGuard guard(interrupt_lock_); set_check_local_interrupts(); Object* wait = waiting_object_.get(); if(park_->parked_p()) { park_->unpark(); return true; } else if(interrupt_with_signal_) { #ifdef RBX_WINDOWS // TODO: wake up the thread #else pthread_kill(os_thread_, SIGVTALRM); #endif interrupt_lock_.unlock(); // Wakeup any locks hanging around with contention memory()->release_contention(state); return true; } else if(!wait->nil_p()) { // We shouldn't hold the VM lock and the IH lock at the same time, // other threads can grab them and deadlock. InflatedHeader* ih = wait->inflated_header(state); interrupt_lock_.unlock(); ih->wakeup(state, wait); return true; } else { Channel* chan = waiting_channel_.get(); if(!chan->nil_p()) { interrupt_lock_.unlock(); memory()->release_contention(state); chan->send(state, cNil); return true; } else if(custom_wakeup_) { interrupt_lock_.unlock(); memory()->release_contention(state); (*custom_wakeup_)(custom_wakeup_data_); return true; } return false; } }
bool VM::wakeup(STATE, GCToken gct, CallFrame* call_frame) { SYNC(state); set_check_local_interrupts(); Object* wait = waiting_object_.get(); if(park_->parked_p()) { park_->unpark(); return true; } else if(vm_jit_.interrupt_with_signal_) { #ifdef RBX_WINDOWS // TODO: wake up the thread #else pthread_kill(os_thread_, SIGVTALRM); #endif UNSYNC; // Wakeup any locks hanging around with contention om->release_contention(state, gct, call_frame); return true; } else if(!wait->nil_p()) { // We shouldn't hold the VM lock and the IH lock at the same time, // other threads can grab them and deadlock. InflatedHeader* ih = wait->inflated_header(state); UNSYNC; ih->wakeup(state, gct, call_frame, wait); return true; } else { Channel* chan = waiting_channel_.get(); if(!chan->nil_p()) { UNSYNC; om->release_contention(state, gct, call_frame); chan->send(state, gct, cNil, call_frame); return true; } else if(custom_wakeup_) { UNSYNC; om->release_contention(state, gct, call_frame); (*custom_wakeup_)(custom_wakeup_data_); return true; } return false; } }