Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
void ofxTimeline::timelineChanged(){
	sortEvents();
	resetCurrentEvent();
}
Ejemplo n.º 4
0
bool EventRecorder::compareNoOrder()
{
    sortEvents();
    return compare();
}
Ejemplo n.º 5
0
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;
}