/*void check_scheduled_tasks( void ) { unsigned idx; unsigned count; time_t now; if (p_task_list) { now = poltime(NULL); count = p_task_list->count(); for( idx = 0; idx < count; idx++ ) { ScheduledTask *task = (*p_task_list)[idx]; if (task->ready(now)) { task->execute(now); } if (task->cancelled) { p_task_list->remove( idx ); delete task; } } } } */ void check_scheduled_tasks( polclock_t* clocksleft, bool* pactivity ) { THREAD_CHECKPOINT( tasks, 101 ); TaskScheduler::cleanse(); polclock_t now_clock = polclock(); TRACEBUF_ADDELEM( "check_scheduled_tasks now_clock", now_clock ); bool activity = false; passert( !task_queue.empty() ); THREAD_CHECKPOINT( tasks, 102 ); for ( ;; ) { THREAD_CHECKPOINT( tasks, 103 ); ScheduledTask* task = task_queue.top(); TRACEBUF_ADDELEM( "check_scheduled_tasks toptask->nextrun", task->next_run_clock() ); THREAD_CHECKPOINT( tasks, 104 ); if ( !task->ready( now_clock ) ) { *clocksleft = task->clocksleft( now_clock ); *pactivity = activity; TRACEBUF_ADDELEM( "check_scheduled_tasks clocksleft", *clocksleft ); return; } THREAD_CHECKPOINT( tasks, 105 ); if ( !task->late( now_clock ) ) { INC_PROFILEVAR( tasks_ontime ); } else { INC_PROFILEVAR( tasks_late ); INC_PROFILEVAR_BY( tasks_late_ticks, task->ticks_late( now_clock ) ); } THREAD_CHECKPOINT( tasks, 106 ); task_queue.pop(); THREAD_CHECKPOINT( tasks, 107 ); task->execute( now_clock ); THREAD_CHECKPOINT( tasks, 108 ); activity = true; if ( task->cancelled ) { THREAD_CHECKPOINT( tasks, 109 ); delete task; } else { THREAD_CHECKPOINT( tasks, 110 ); task_queue.push( task ); } THREAD_CHECKPOINT( tasks, 111 ); } }
bool OSExecutorModule::signal_event( BObjectImp* imp ) { INC_PROFILEVAR(events); if (blocked_ && (wait_type == WAIT_EVENT)) // already being waited for { /* Now, the tricky part. The value to return on an error or completion condition has already been pushed onto the value stack - so, we need to replace it with the real result. */ exec.ValueStack.top().set( new BObject( imp ) ); /* This executor will get moved to the run queue at the next step_scripts(), where blocked is checked looking for timed out or completed operations. */ revive(); } else // not being waited for, so queue for later. { if (events_.size() < max_eventqueue_size) { events_.push( imp ); } else { if (config.discard_old_events) { BObject ob( events_.front() ); events_.pop(); events_.push( imp ); } else { if (config.loglevel >= 11) { cout << "Event queue for " << exec.scriptname() << " is full, discarding event." << endl; ExecutorModule* em = exec.findModule( "npc" ); if (em) { NPCExecutorModule* npcemod = static_cast<NPCExecutorModule*>(em); cout << "NPC Serial: " << hexint( npcemod->npc.serial ) << " (" << npcemod->npc.x << " " << npcemod->npc.y << " " << (int) npcemod->npc.z << ")" << endl; } BObject ob( imp ); cout << "Event: " << ob->getStringRep() << endl; } return false; } } } return true; }
void check_blocked( polclock_t* pclocksleft ) { polclock_t now_clock = polclock(); sleep_cycles += holdlist.size() + notimeoutholdlist.size(); polclock_t clocksleft = POLCLOCKS_PER_SEC * 60; for(;;) { THREAD_CHECKPOINT( scripts, 131 ); HoldList::iterator itr = holdlist.begin(); if (itr == holdlist.end()) break; UOExecutor* ex = (*itr).second; // ++ex->sleep_cycles; passert( ex->os_module->blocked_ ); passert( ex->os_module->sleep_until_clock_ != 0 ); clocksleft = ex->os_module->sleep_until_clock_ - now_clock; if ( clocksleft <= 0 ) { if (clocksleft == 0) INC_PROFILEVAR( scripts_ontime ); else INC_PROFILEVAR( scripts_late ); // wakey-wakey // read comment above to understand what goes on here. // the return value is already on the stack. THREAD_CHECKPOINT( scripts, 132 ); ex->os_module->revive(); } else { break; } } *pclocksleft = clocksleft; }