int Scheduler::runNormal() { std::cout << "Event-pass mode" << std::endl; std::cout << std::endl; // Current data std::cout << "Current time: " << currentTime << std::endl; std::cout << "Have lock: " << (haveLock ? "Yes" : "No") << std::endl; std::cout << std::endl; logStatus("Rescheduling Events"); // Scan database Scan_Report report = scanEvents(); // Stats std::cout << "Total events: " << report.getEventCount() << std::endl; std::cout << std::endl; std::cout << "Dropped " << report.getDropped() << " missed events" << std::endl; std::cout << "Rescheduled " << report.getResched() << " missed events" << std::endl; std::cout << "Total missed events: " << report.getTotalMissed() << std::endl; // Current events std::vector<Event> now = report.getNow(); sortEvents(now); if (now.size() > 0) { std::cout << std::endl; std::cout << "Current events:" << std::endl; for (int i = 0; i < now.size(); i++) { std::cout << now[i].getComment() << std::endl; } Event event = now[0]; if (isSilenActive()) { haveLock = false; } if (haveLock) { int wait = event.getSec_offset() - currentTime.getSeconds(); if (wait > 0) { logStatus("Waiting to perform event - " + event.getComment()); usleep(wait * 1000000); } logStatus("Performing event - " + event.getComment()); perform(event); } } return 0; }
/** * Runs the tasks according to the schedule specified. */ int schedulerRun(TaskArray* tasks, Event* events, StringInfoBlock* string_info) { int runningFinished = 0; int current_time = 0; int first_incompleted_event = 0; int incomp_break = 0; int current_event = 0; int event_count = tasks->size * 2; int blockNumber; int stateNumber, subSubNumber; int cpar; int status; int current_command; int commandCount = 0; //int execvp_result = 0; Task* cur_task; int* convs; char* in_exec[MAX_PARAM]; // no schedule yet setbuf(stdout, 0); setbuf(stderr, 0); while(!runningFinished) { shmLock(); if (first_incompleted_event == event_count) runningFinished = 1; incomp_break = 0; for(current_event = first_incompleted_event; current_event < event_count; current_event++) { //printf("Current event number: %i\n", current_event); if (events[current_event].time > current_time) break; //printf("First incompleted event: %i, event_count %i.\n", first_incompleted_event, event_count); //printf("Event number %i: is done -- %i.\n", current_event, events[current_event].done); if (events[current_event].done) { if (!incomp_break) first_incompleted_event++; } else { if (events[current_event].action == ACTION_START) { if (!dependentTasksFinished(tasks, events, string_info, current_event)) { //printf("!!! Dependency failed for event %i (id %i)\n", current_event, events[current_event].id); incomp_break = 1; continue; } } for(cpar = 0; cpar < event_count; cpar++) { if ( (events[cpar].action == ACTION_WAIT) && (events[cpar].id == events[current_event].id) ) { if ( events[cpar].time != current_time + events[cpar].max_time ) { events[cpar].time = current_time + events[cpar].max_time; sortEvents(events, event_count); break; } } } events[current_event].done = 1; //printf("Now event %i is considered to be done.\n", current_event); //printf("Increased first incompleted event number.\n"); if (!incomp_break) first_incompleted_event++; commandCount = 0; switch(events[current_event].action) { case ACTION_START: for(blockNumber = 0; blockNumber < string_info->size; blockNumber++) { if (string_info->blocks[blockNumber]->id == events[current_event].id) { //blockPrint(string_info->blocks[blockNumber]); break; } } //printf("string_info_block_size for block number %i: %i\n", blockNumber, //string_info->blocks[blockNumber]->size); for(stateNumber = 0; stateNumber < string_info->blocks[blockNumber]->size; stateNumber++) if (string_info->blocks[blockNumber]->states[stateNumber] == PROGRAM_NAME) commandCount++; cur_task = taskGetById(tasks, events[current_event].id); //printf("Current task cmdline: %s\n", cur_task->command); cur_task->state = STATE_RUNNING; sprintf(err_string, "Starting task with id %i.", events[current_event].id); printError(err_string); if (commandCount == 1) // only one command { //printf("Block num: %i\n", blockNumber); string_info->blocks[blockNumber]->characters[0] = *(string_info->blocks[blockNumber]->endings[0]); *(string_info->blocks[blockNumber]->endings[0]) = 0; //printf("Command at block %i: %s\n", blockNumber, string_info->blocks[blockNumber]->beginnings[0]); cur_task->pid_count = 1; for(stateNumber = 1; stateNumber < string_info->blocks[blockNumber]->size; stateNumber++) { if (string_info->blocks[blockNumber]->states[stateNumber] == PARAMETER) { string_info->blocks[blockNumber]->characters[stateNumber] = *(string_info->blocks[blockNumber]->endings[stateNumber]); *(string_info->blocks[blockNumber]->endings[stateNumber]) = 0; in_exec[stateNumber] = string_info->blocks[blockNumber]->beginnings[stateNumber]; //printf("par %s\n", in_exec[stateNumber]); } else break; } in_exec[0] = string_info->blocks[blockNumber]->beginnings[0]; //printf("in_exec[0] = %s\n", string_info->blocks[blockNumber]->beginnings[0]); //printf("stateNumber = %i here\n", stateNumber); in_exec[stateNumber] = NULL; //printf("in_exec stateNumber: %i\n", stateNumber); if ((cur_task->pids[0] = fork()) != 0) { if (cur_task->pids[0] == -1) { // fork failed printError("Fork failed."); shmUnlock(); return 1; } } else { // child process /*execvp_result = */ execvp(string_info->blocks[blockNumber]->beginnings[0], in_exec); // assume that this never happens //printf("Error %i while doing execvp(). DIE!\n", execvp_result); exit(1); } // restore the character back *(string_info->blocks[blockNumber]->endings[0]) = string_info->blocks[blockNumber]->characters[0]; for(stateNumber = 1; stateNumber < string_info->blocks[blockNumber]->size; stateNumber++) if (string_info->blocks[blockNumber]->states[stateNumber] == PARAMETER) { *(string_info->blocks[blockNumber]->endings[stateNumber]) = string_info->blocks[blockNumber]->characters[stateNumber]; } else break; } else { convs = malloc(sizeof(int) * 2 * (commandCount - 1)); if (!convs) { printError(MSG_NOT_ENOUGH_MEMORY); return 1; } for(stateNumber = 0; stateNumber < commandCount - 1; stateNumber++) { if (pipe(&convs[2 * stateNumber]) < 0) { printError("Error creating pipe.\n"); shmUnlock(); return 1; } } cur_task->pid_count = commandCount; //printf("Current task pid count is %i\n", cur_task->pid_count ); for(stateNumber = 0; stateNumber < commandCount; stateNumber++) { if ((cur_task->pids[stateNumber] = fork()) != 0) { if (cur_task->pids[stateNumber] == -1) { printError("Fork failed."); shmUnlock(); return 1; } } else { // child process if (stateNumber == 0) { //printf("\t ---in child 1\n"); close(1); if (dup2(convs[1], 1) < 0) { //fprintf(stderr, "CHILD %i: error dupping descriptor\n", stateNumber); printError("Couldn't peform dup() call.\n"); shmUnlock(); return 1; } } else if (stateNumber == commandCount - 1) { //printf("\t ---in last-child 1\n"); close(0); if (dup2(convs[2 * (commandCount - 2)], 0) < 0) { //fprintf(stderr, "CHILD %i: error dupping descriptor %i\n", stateNumber, // convs[2 * (commandCount - 1)]); printError("Couldn't peform dup() call.\n"); shmUnlock(); return 1; } } else { //printf("\t ---in mid-child 1\n"); close(0); close(1); dup2(convs[2 * (stateNumber - 1)], 0); dup2(convs[2 * stateNumber + 1], 1); }; // close pipes that are not needed for(cpar = 0; cpar < commandCount - 1; cpar++) { close(convs[2 * cpar]); close(convs[2 * cpar + 1]); } // exec! current_command = 0; for(cpar = 0; cpar < string_info->blocks[blockNumber]->size; cpar++) { if (string_info->blocks[blockNumber]->states[cpar] == PROGRAM_NAME) { if (current_command == stateNumber) { string_info->blocks[blockNumber]->characters[0] = *(string_info->blocks[blockNumber]->endings[cpar]); *(string_info->blocks[blockNumber]->endings[cpar]) = 0; break; } current_command++; } } in_exec[0] = string_info->blocks[blockNumber]->beginnings[cpar]; //fprintf(stderr, "CHILD %i: cmd %s number %i\n", stateNumber, // string_info->blocks[blockNumber]->beginnings[cpar], stateNumber); for(subSubNumber = cpar + 1; subSubNumber < string_info->blocks[blockNumber]->size; subSubNumber++) { if (string_info->blocks[blockNumber]->states[subSubNumber] == PARAMETER) { string_info->blocks[blockNumber]->characters[subSubNumber] = *(string_info->blocks[blockNumber]->endings[subSubNumber]); *(string_info->blocks[blockNumber]->endings[subSubNumber]) = 0; in_exec[subSubNumber - cpar] = string_info->blocks[blockNumber]->beginnings[subSubNumber]; //fprintf(stderr, "CHILD %i: in_exec[%i] = %s\n", stateNumber, subSubNumber - cpar, // string_info->blocks[blockNumber]->beginnings[subSubNumber]); //fprintf(stderr, "CHILD %i: Param %s\n", stateNumber, in_exec[subSubNumber - cpar]); } else break; } in_exec[subSubNumber - cpar] = 0; // start the command finally /*execvp_result = */ execvp(string_info->blocks[blockNumber]->beginnings[cpar], in_exec); //fprintf(stderr, "CHILD %i: Error %i while doing execvp(). DIE!\n", stateNumber, //execvp_result); exit(0); // for security } } //printf("Closing pipes in main\n"); for(stateNumber = 0; stateNumber < commandCount - 1; stateNumber++) { close(convs[2 * stateNumber]); close(convs[2 * stateNumber + 1]); } free(convs); } break; case ACTION_WAIT: cur_task = taskGetById(tasks, events[current_event].id); //printf("We're calling WAIT\n"); if (waitpid(cur_task->pids[cur_task->pid_count - 1], &status, WNOHANG)) { cur_task->result = WEXITSTATUS(status); sprintf(err_string, "Task with id %i (pid %i) finished.", events[current_event].id, cur_task->pids[cur_task->pid_count - 1]); printError(err_string); cur_task->state = STATE_FINISHED; } else { for(cpar = 0; cpar < cur_task->pid_count; cpar++) kill(cur_task->pids[cpar], SIGINT); sprintf(err_string, "Task with id %i (pid %i) killed.", events[current_event].id, cur_task->pids[cur_task->pid_count - 1]); printError(err_string); cur_task->state = STATE_KILLED; } break; default: printError("Unknown action\n"); shmUnlock(); return 1; } } } shmUnlock(); sleep(1); //printf("%i secs passed\n", current_time); current_time++; } return 0; }
void ofxTimeline::timelineChanged(){ sortEvents(); resetCurrentEvent(); }
bool EventRecorder::compareNoOrder() { sortEvents(); return compare(); }
bool MxmlMeasure::parseMeasure(xml_node mel) { bool output = true; vector<vector<int> > staffVoiceCounts; setStartTimeOfMeasure(); HumNum starttime = getStartTime(); HumNum st = starttime; HumNum maxst = starttime; xml_node nextel; for (auto el = mel.first_child(); el; el = el.next_sibling()) { MxmlEvent* event = new MxmlEvent(this); m_events.push_back(event); nextel = el.next_sibling(); output &= event->parseEvent(el, nextel, starttime); starttime += event->getDuration(); if (starttime > maxst) { maxst = starttime; } } setDuration(maxst - st); // Should no longer be needed: // calculateDuration(); bool needdummy = false; MxmlMeasure* pmeasure = getPreviousMeasure(); if (getTimeSigDur() <= 0) { if (pmeasure) { setTimeSigDur(pmeasure->getTimeSigDur()); } } if (getDuration() == 0) { if (pmeasure) { setDuration(pmeasure->getTimeSigDur()); } else { setTimeSigDur(getTimeSigDur()); } needdummy = true; } // Maybe check for overfull measures around here if (needdummy || getEventCount() == 0) { // if the duration of the measure is zero, then set the duration // of the measure to the duration of the time signature // This is needed for certain cases of multi-measure rests, where no // full-measure rest is given in the measure (Sibelius does this). setDuration(getTimeSigDur()); addDummyRest(); } // Neeed to check for empty voice/layers occuring lower in the // voice index list than layers which contain notes. For example // if voice/layer 2 contains notes, but voice/layer 1 does not, then // a dummy full-measure rest should fill voice/layer 1. The voice // layer 1 should be filled with the duration of the measure according // to the other voice/layers in the measure. This is done later // after a voice analysis has been done in // musicxml2hum_interface::insertMeasure(), specifically: // musicxml2hum_interface::checkForDummyRests(). sortEvents(); return output; }