Changeset - f26936aa69e0
[Not reviewed]
default
0 1 0
Nathan Brink (binki) - 16 years ago 2010-01-03 12:52:04
ohnobinki@ohnopublishing.net
cleanup distrend_do_config() slightly
1 file changed with 5 insertions and 15 deletions:
0 comments (0 inline, 0 general)
src/server/distrend.c
Show inline comments
 
@@ -154,194 +154,194 @@ void finish_frame(struct general_info *g
 
  distrenjob->completed_frames ++;
 
  distrenjob->assigned_frames --;
 
  geninfo->total_frames_rendered ++; /*< Increase total frames var for stats */
 

	
 
  update_general_info(geninfo);
 
  updateJobStatsXML(distrenjob);
 
}
 

	
 
/**
 
   checks to see if a job is actually done.
 
   - scans the folder of the job to make sure all output files are present
 
*/
 
int mortition(struct general_info *geninfo, struct distrenjob *job)
 
{
 
  short int isJobDone;
 
  int counter;
 
  char *path_and_number;
 
  struct stat buffer;
 

	
 
  isJobDone = 1;
 
  for(counter = 0; counter < job->total_frames; counter++)
 
    {
 
      _distren_asprintf(&path_and_number, "%s/stor/job%d/out/%d.%s",
 
			geninfo->config->datadir,
 
			job->jobnum,
 
			job->frameset[counter].num,
 
			job->output_format);
 
      if(stat(path_and_number, &buffer) == -1)
 
        {
 
	  /**
 
	     missing frame found
 
	   */
 
          job->frameset[counter].status = FRAMESETSTATUS_UNASSIGNED;
 
          job->completed_frames--;
 
          geninfo->total_frames_rendered--;
 
          isJobDone = 0;
 
        }
 
      free(path_and_number);
 
    }
 

	
 
  if(isJobDone)
 
    {
 
      /**
 
	 all frames were accounted for
 
      */
 
      distrenjob_remove(geninfo, job);
 
      distrenjob_free(&job);
 
      geninfo->jobs_in_queue --;
 
      update_xml_joblist(geninfo);
 
    }
 
  else
 
    /**
 
       if the job isn't done, have frame_finder() start from the first frame, allowing it to see the frames that are now unassigned 
 
    */
 
    job->prev_frame_index = -1;
 

	
 
  update_general_info(geninfo);
 

	
 
  return 0;
 
}
 

	
 
/**
 
   scans the frames of a job to initialize a job after server
 
   @return 0 if the job is completely done and there are no missing frames,
 
           1 if missing frames are found.
 
*/
 
int restoreJobState(struct distrenjob *job)
 
{
 
  short int isJobDone;
 
  int counter;
 
  char *path_and_number;
 
  struct stat buffer;
 

	
 
  isJobDone = 1;
 
  for(counter = 0; counter < job->total_frames; counter++)
 
    {
 
      _distren_asprintf(&path_and_number, "stor/job%d/out/%d.%s", job->jobnum, job->frameset[counter].num, job->output_format); /*< @TODO this path is used in multiple places, construct/build/determine it in a central function */
 
      if(stat(path_and_number, &buffer) == 0)
 
        {
 
          job->frameset[counter].status = FRAMESETSTATUS_ASSIGNED;
 
          job->completed_frames++;
 
        }
 
      else
 
        isJobDone = 0;
 
      free(path_and_number);
 
    }
 

	
 
  return !isJobDone;
 
}
 

	
 
/**
 
   creates a structure from starting data, then calls another
 
   function to actually add that struct to the queue.
 
*/
 
int prepare_distrenjob(struct general_info *geninfo, int type, char *name, char *submitter, char *email, int priority, int start_frame, int end_frame, int width, int height)
 
{
 
  int counter;
 
  int counter2;
 
  int counter;
 
  int tmp;
 
  char *path_with_num;
 
  char *serialfile;
 

	
 
  struct distrenjob *distrenjob;
 
  tmp = distrenjob_new(&distrenjob);
 
  if(tmp)
 
    return 1;
 

	
 
  geninfo->highest_jobnum ++;
 
  distrenjob->jobnum = geninfo->highest_jobnum;
 

	
 
  distrenjob->type = 1;
 
  distrenjob->name = name;
 
  distrenjob->submitter = submitter;
 
  distrenjob->email = email;
 
  distrenjob->priority = priority;
 
  distrenjob->width = width;
 
  distrenjob->height = height;
 
  /** sets the total number of frames in animation for status purposes */
 
  distrenjob->total_frames = (end_frame - start_frame + 1);
 
  distrenjob->frameset = malloc(sizeof(struct frameset) * distrenjob->total_frames);
 
  if(!distrenjob->frameset)
 
    {
 
      distrenjob_free(&distrenjob);
 
      return 1;
 
    }
 

	
 
  /** prepares all the frames by setting that status to "unassigned" */
 
  counter2 = start_frame;
 
  for(counter = 0; counter < distrenjob->total_frames; counter++){
 
    distrenjob->frameset[counter].num = counter2;
 
    distrenjob->frameset[counter].status = FRAMESETSTATUS_UNASSIGNED;
 

	
 
    counter2++;
 
  }
 

	
 
  _distren_asprintf(&path_with_num, "stor/job%d/out/", distrenjob->jobnum);
 
  fprintf(stderr, ">>NOT<< creating dir ``%s''\n", path_with_num); /*< @TODO recursively create job directory */
 
  serialfile = job_getserialfilename(geninfo, distrenjob->jobnum);
 

	
 
  free(path_with_num);
 

	
 
  /**
 
     add job to queue
 
  */
 
  fprintf(stderr, "\nprepare_distrenjob: attempting distrenjob_serialize()\n");
 
  distrenjob_serialize(distrenjob, serialfile);
 
  free(serialfile);
 

	
 
  fprintf(stderr, "\nprepare_distrenjob: attempting distrenjob_enqueue()\n");
 
  distrenjob_enqueue(geninfo, distrenjob);
 

	
 
  geninfo->jobs_in_queue ++;
 
  fprintf(stderr, "\nprepare_distrenjob: attempting update_xml_joblist()\n");
 
  update_xml_joblist(geninfo);
 
  fprintf(stderr, "\nprepare_distrenjob: attempting update_general_info()\n");
 
  update_general_info(geninfo);
 
  fprintf(stderr, "\nprepare_distrenjob: attempting updateJobStatsXML()\n");
 
  updateJobStatsXML(distrenjob);
 

	
 
  return 0;
 
}
 

	
 

	
 
/**
 
   distrenjob_enqueue: This function adds the job to the queue based on its priority
 
*/
 
int distrenjob_enqueue(struct general_info *geninfo, struct distrenjob *job)
 
{
 
  struct distrenjob *prev_job;
 
  struct distrenjob *current_job;
 
  struct distrenjob *head;
 

	
 
  head = &geninfo->head;
 
  prev_job = head;
 

	
 
  /**
 
     iterate through linked jobs
 
  */
 
  for(current_job = head->next; current_job; current_job = current_job->next)
 
  {
 
    fprintf(stderr, "enqueue loop iteration\n");
 
    if(job->priority < current_job->priority)
 
      {
 
	/**
 
	   if job's priority is less than current_job's priority, insert job
 
	   keep in mind 1 is the highest priority given to jobs, head has a
 
	   priority of zero so it will always be before other jobs
 
	*/
 
	prev_job->next = job;
 
	job->next = current_job;
 
	fprintf(stderr, "adding job before jobname: %s\n", current_job->name);
 

	
 
	return 0;
 
      }
 
@@ -579,203 +579,193 @@ void frame_watchdog(struct distrenjob *d
 
  unsigned int counter;
 

	
 
  for(distrenjob_ptr = distrenjob_head->next; distrenjob_ptr; distrenjob_ptr = distrenjob_ptr->next)
 
  /* iterate through jobs */
 
  {
 
    /* if the job has been started, checks by seeing if either to first or second frame has been started */
 
    if(distrenjob_ptr->frameset[0].status != FRAMESETSTATUS_UNASSIGNED || distrenjob_ptr->frameset[1].status != FRAMESETSTATUS_UNASSIGNED)
 
      /* iterate through all frames for this job: */
 
      for(counter = 0; counter < distrenjob_ptr->total_frames; counter ++)
 
	    /*watchdog_forgiveness = seconds of forgiveness before frame is re-assigned: */
 
        if((distrenjob_ptr->frameset[counter].start_time + distrenjob_ptr->watchdog_forgiveness) < clock())
 
        {
 
            /*
 
            If frame is not completed within the number of seconds specified by watchdog_forgiveness
 
            Then change the frame status to unassigned
 
            */
 
            distrenjob_ptr->frameset[counter].status = FRAMESETSTATUS_UNASSIGNED;
 
            distrenjob_ptr->assigned_frames--;
 
        }
 

	
 
    updateJobStatsXML(distrenjob_ptr);
 
  }
 
}
 

	
 
/**
 
   Finds a distrenjob struct based on the jobnum
 
   @arg jobnum job number to search for
 
   @return NULL on job doesn't exist
 
 */
 
struct distrenjob *distrenjob_get(struct distrenjob *head, jobnum_t jobnum)
 
{
 
  struct distrenjob *distrenjob_ptr;
 

	
 
  /*
 
    The conditions of the for loop will leave distrenjob_ptr at NULL if the end of the list is reached. It will leave it pointing to the correct job if it is found.
 
   */
 
  for(distrenjob_ptr = head;
 
      distrenjob_ptr
 
        && distrenjob_ptr->jobnum != jobnum;
 
      distrenjob_ptr = distrenjob_ptr->next);
 

	
 
  return distrenjob_ptr;
 
}
 

	
 

	
 
/**
 
   Removes a distrenjob from the distrenjob linked list. It does not free the distrenjob, however. You should do that with distrenjob_free() from distrenjob.h
 

	
 
   @arg head pointer to the head of the linkedlist of distrenjobs
 
 */
 
void distrenjob_remove(struct general_info *geninfo, struct distrenjob *bj)
 
{
 
  struct distrenjob *previous_distrenjob;
 

	
 
  for(previous_distrenjob = &geninfo->head;
 
      previous_distrenjob
 
	&& previous_distrenjob->next != bj; /*< stop on the distrenjob that comes before bj */
 
      previous_distrenjob = previous_distrenjob->next)
 
    ;
 

	
 
  /*
 
    This removes references to bj from the linked list. I.E., we now skip bj when iterating through the list
 
  */
 
  previous_distrenjob->next = bj->next;
 

	
 
  geninfo->jobs_in_queue --;
 
}
 

	
 

	
 
/* Grabs config info from confs */
 
int distrend_do_config(int argc, char *argv[], struct distrend_config **config)
 
{
 
  unsigned int counter;
 

	
 
  cfg_opt_t myopts_listen[] =
 
    {
 
      CFG_SIMPLE_STR("type", NULL),
 
      CFG_SIMPLE_STR("path", NULL),
 
      CFG_SIMPLE_INT("port", NULL),
 
      CFG_END()
 
    };
 
  cfg_opt_t myopts[] =
 
    {
 
      CFG_SEC("listen",  /* this must be imported into struct listens (which must still be declared) */
 
          myopts_listen,
 
          CFGF_MULTI),
 
      CFG_SIMPLE_STR("datadir", NULL),
 
      CFG_STR_LIST("render_types", NULL, CFGF_NONE),
 
      CFG_END()
 
    };
 

	
 
  struct distrenjob *distrenjob;
 
  cfg_t *cfg_listen;
 

	
 
  int tmp;
 

	
 
  /*
 
   * test distrenjob_unserialize()
 
   */
 
  tmp = distrenjob_unserialize(&distrenjob, "distrenjob.xml.example");
 
  if(tmp)
 
    fprintf(stderr, "distrenjob_unserialize() returned %d. Try to cd to distren/doc if you want to test out the distrenjob_unserialize() function. (This will only fix this error if the error is due to an inability of the xml library to access distrenjob.xml.example)\n\n", tmp);
 
  else
 
    fprintf(stderr, "using email ``%s'' for user ``%s'' -- reading in XML files and pulling data from them using libxml2+XPath works!!!\n", distrenjob->email, distrenjob->submitter);
 

	
 
  fprintf(stderr, "%s:%d running config\n", __FILE__, __LINE__);
 

	
 
  fprintf(stderr, "%s:%d: running config\n", __FILE__, __LINE__);
 
  *config = malloc(sizeof(struct distrend_config));
 
  myopts[1].simple_value = &(*config)->datadir;
 

	
 
  if(options_init(argc, argv, &(*config)->mycfg, myopts, "daemon", &(*config)->options))
 
    return 1;
 

	
 
  /**
 
     grab listen blocks:
 
   */
 
  (*config)->listens = malloc(sizeof(struct distrend_listen) * (cfg_size((*config)->mycfg, "listen") + 1));
 
  for(counter = 0; counter < cfg_size((*config)->mycfg, "listen"); counter ++)
 
    {
 
      cfg_listen = cfg_getnsec((*config)->mycfg, "listen", counter);
 
      (*config)->listens[counter].port = cfg_getint(cfg_listen, "port");
 
      (*config)->listens[counter].sock = -1;
 
    }
 
  memset(&(*config)->listens[counter], '\0', sizeof(struct distrend_listen));
 

	
 
  fprintf(stderr, "using %s as datadir\n", (*config)->datadir);
 

	
 
  return 0;
 
}
 
int distrend_config_free(struct distrend_config *config)
 
{
 
  options_free(config->options);
 
  free(config);
 

	
 
  return 0;
 
}
 
/* ************************** XML Functions ************************* */
 

	
 
// writes the general_info.xml file which is a copy of the general_info structure
 
// except that it doesn't hold free_clients and rendering_clients
 
void update_general_info(struct general_info *geninfo)
 
{
 
  xmlTextWriterPtr writer;
 
  char *tmp;
 

	
 
  writer = xmlNewTextWriterFilename("general_info.xml", 0);
 
  xmlTextWriterStartDocument(writer, NULL, "utf-8", NULL);
 

	
 
  xmlTextWriterStartElement(writer, (xmlChar*)"general_info");
 

	
 
  _distren_asprintf(&tmp, "%d", geninfo->jobs_in_queue);
 
  xmlTextWriterWriteElement(writer, (xmlChar*)"jobs_in_queue", (xmlChar*)tmp);
 
  free(tmp);
 

	
 
  _distren_asprintf(&tmp, "%d", geninfo->total_finished_jobs);
 
  xmlTextWriterWriteElement(writer, (xmlChar*)"total_finished_jobs", (xmlChar*)tmp);
 
  free(tmp);
 

	
 
  _distren_asprintf(&tmp, "%d", geninfo->total_frames_rendered);
 
  xmlTextWriterWriteElement(writer, (xmlChar*)"total_frames_rendered", (xmlChar*)tmp);
 
  free(tmp);
 

	
 
  _distren_asprintf(&tmp, "%d", geninfo->highest_jobnum);
 
  xmlTextWriterWriteElement(writer, (xmlChar*)"highest_jobnum", (xmlChar*)tmp);
 
  free(tmp);
 

	
 
  xmlTextWriterEndDocument(writer);
 
  xmlFreeTextWriter(writer);
 
}
 

	
 
// this reads the information from general_info.xml to the general_info structure
 
int import_general_info(struct general_info *general_info)
 
{
 
  xmlDocPtr doc;
 
  xmlNodePtr cur;
 

	
 
  doc = xmlParseFile("general_info.xml");
 
  cur = xmlDocGetRootElement(doc);
 
  if (xmlStrcmp(cur->name, (xmlChar*)"general_info"))
 
    {
 
      fprintf(stderr, "xml document is wrong type");
 
      xmlFreeDoc(doc);
 
      return 1;
 
    }
 

	
 
  cur = cur->xmlChildrenNode;
 
  general_info->jobs_in_queue = atoi((char*)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1));
 
  cur = cur->next;
 
  general_info->total_finished_jobs = atoi((char*)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1));
 
  cur = cur->next;
 
  general_info->total_frames_rendered = atoi((char*)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1));
 
  cur = cur->next;
 
  general_info->highest_jobnum = atoi((char*)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1));
 

	
 
  general_info->hibernate = 0;
 
  general_info->free_clients = 0;
 
  general_info->rendering_clients = 0;
 
  general_info->timestamp = 0;
 
  general_info->total_render_power = 0;
 
  general_info->total_priority_pieces = 0;
 

	
 
  xmlFreeDoc(doc);
 

	
 
@@ -1041,252 +1031,252 @@ int reCreateQueueFromXML(struct general_
 
  job = createJobFromXML(geninfo, job_num);
 
  if(job == NULL)
 
    return 1;
 

	
 
  /**
 
     insert job at front of the queue
 
  */
 
  geninfo->head.next = job;
 
  job->next = holder;
 

	
 
  return 0;
 
}
 

	
 
/* ************************** Test Functions ************************* */
 
int printFrameInfo(struct frameset *frame)
 
{
 
  char *status;
 

	
 
  status = NULL;
 

	
 
  switch(frame->status)
 
  {
 
    case FRAMESETSTATUS_UNASSIGNED:
 
      _distren_asprintf(&status, "%s", "unassigned");
 
      break;
 
    case FRAMESETSTATUS_ASSIGNED:
 
      _distren_asprintf(&status, "%s", "assigned");
 
      break;
 
    case FRAMESETSTATUS_DONE:
 
      _distren_asprintf(&status, "%s", "completed");
 
      break;
 
    case FRAMESETSTATUS_CANCELED:
 
      _distren_asprintf(&status, "%s", "canceled");
 
  }
 

	
 
  printf("frame #: %d --> %s\n", frame->num, status);
 
  free(status);
 

	
 
  return 0;
 
}
 

	
 
int printJob(struct distrenjob *job)
 
{
 
  int counter;
 
  fprintf(stderr, "frame_num: status\n");
 
  for(counter = 0; counter < job->total_frames; counter++)
 
    {
 
      printFrameInfo(&job->frameset[counter]);
 
    }
 

	
 
  return 1;
 
}
 

	
 
int printJobInfo(struct distrenjob *job)
 
{
 
  fprintf(stderr, "type: %d\n", job->type);
 
  fprintf(stderr, "name: %s\n", job->email);
 
  fprintf(stderr, "submitter: %s\n", job->submitter);
 
  fprintf(stderr, "e-mail: %s\n", job->email);
 
  fprintf(stderr, "priority: %d\n", job->priority);
 
  fprintf(stderr, "completed: %d\n", job->completed_frames);
 
  fprintf(stderr, "assigned: %d\n", job->assigned_frames);
 
  fprintf(stderr, "total: %d\n", job->total_frames);
 
  fprintf(stderr, "watchdog: %d\n", job->watchdog_forgiveness);
 
  fprintf(stderr, "hibernate: %d\n", job->hibernate);
 
  fprintf(stderr, "prev_frame: %d\n", job->prev_frame_index);
 
  fprintf(stderr, "render power: %ld\n", job->assigned_render_power);
 

	
 
  return 1;
 
}
 

	
 
int printAllJobnums(struct distrenjob *head)
 
{
 
  struct distrenjob *current_job;
 
  int total_jobs;
 
  fprintf(stderr, "job numbers in the order they will be processed:\n");
 

	
 
  total_jobs = 0;
 
  for(current_job = head->next; current_job; current_job = current_job->next)
 
    {
 
      fprintf(stderr, "%d: %s\n", current_job->jobnum, current_job->name);
 
      total_jobs++;
 
    }
 

	
 
  fprintf(stderr, "\n%d jobs in queue\n\n", total_jobs);
 

	
 
  return 1;
 
}
 

	
 
/* ************************** Main ************************* */
 

	
 
int main(int argc, char *argv[])
 
{
 

	
 
  /* Argument-parser */
 
  int counter;
 
  int test; // Interactive test mode if 1
 
  int test; /*< Interactive mode if 1 */
 

	
 
  struct general_info general_info;
 

	
 
  int cont;
 
  struct distrend_clientset *clients;
 

	
 
  enum clientstatus
 
  {
 
    CLIENTSTATUS_UNINITIALIZED = 0,
 
    CLIENTSTATUS_BUSY = 1,
 
    CLIENTSTATUS_IDLE = 2
 
  } clientstatus;
 

	
 
  int command;
 
  jobnum_t jobnum;
 
  struct distrenjob *tmp_job;
 
  struct frameset *tmp_frame;
 
  int type;
 
  char *name;
 
  char *submitter;
 
  char *email;
 
  int priority;
 
  int width;
 
  int height;
 
  int start_frame;
 
  int end_frame;
 
  size_t read_buf;
 

	
 
  xmlinit();
 

	
 
  test = 0;
 
  for(counter = 0; counter < argc; counter ++)
 
    {
 
      if(strcmp(argv[counter], "-h") == 0)
 
      {
 
    	  fprintf(stderr, "Usage: distrend [option] \nStarts the distrend server\n\t-h\tshow this help\n\t-t\tlaunches queue testing interface \n");
 
		  return 2;
 
      }
 

	
 
      else if(strcmp(argv[counter], "-t") == 0)
 
      {
 
    	  fprintf(stderr, "Entering into test mode...\n\n");
 
		  test=1;
 
      }
 
    }
 
  cont = 1;
 

	
 
  if(distrend_do_config(argc, argv, &general_info.config))
 
    return 1;
 

	
 
  if(start_data(&general_info, general_info.config->datadir))
 
    {
 
      fprintf(stderr, "%s:%d: start_data() failed\n", __FILE__, __LINE__);
 
      return 1;
 
    }
 

	
 
  // pre-loaded jobs for testing
 
  /** pre-loaded jobs for testing */
 
  prepare_distrenjob(&general_info, 1, "awesome", "LordOfWar", "onlylordofwar@gmail.com", 8, 1, 100, 640, 480);
 
  prepare_distrenjob(&general_info, 1, "hamburger", "Ohnobinki", "ohnobinki@ohnopublishing.net", 3, 1, 50, 1280, 720);
 
  prepare_distrenjob(&general_info, 1, "hamburger", "ohnobinki", "ohnobinki@ohnopublishing.net", 3, 1, 50, 1280, 720);
 

	
 
  while(test == 1)
 
  {
 
    fprintf(stderr, "Welcome to DistRen Alpha Interactive Test Mode\n\n");
 
    fprintf(stderr, "\t1 \tPrint all frames in a job\n");
 
    fprintf(stderr, "\t2 \tExamine certain job\n");
 
    fprintf(stderr, "\t3 \tGet a frame to render\n");
 
    fprintf(stderr, "\t4 \tAdd a job\n");
 
    fprintf(stderr, "\t5 \tDelete a job\n");
 
    fprintf(stderr, "\t6 \tPrint jobnums in queue\n");
 
    fprintf(stderr, "\t7 \tPrint general info\n");
 
    fprintf(stderr, "\t8 \tQuit\n");
 

	
 
    scanf("%d", &command);
 

	
 
    switch(command)
 
    {
 
    case 1:
 
      fprintf(stderr, "Job number: ");
 
      scanf("%d", &jobnum);
 
      printJob(distrenjob_get(&general_info.head, jobnum));
 
      break;
 
    case 2:
 
      fprintf(stderr, "Job number: ");
 
      scanf("%d", &jobnum);
 
      printJobInfo(distrenjob_get(&general_info.head, jobnum));
 
      break;
 
    case 3:
 
      general_info.total_render_power ++;
 
      if(!find_jobframe_again(&general_info, -1, 1, &tmp_job, &tmp_frame))
 
      {
 
    	  fprintf(stderr, "frame was found, details below\n");
 
          fprintf(stderr, "Job#:%d\n", tmp_job->jobnum);
 
          fprintf(stderr, "Frame#:%d\n", tmp_frame->num);
 
      }
 

	
 
      break;
 
    case 4:
 
      name = NULL;
 
      submitter = NULL;
 
      email = NULL;
 

	
 
      fprintf(stderr, "\nType: \n\t 1 \t blender\n\t 2 \t povray\n"); scanf("%d", &type);
 
      fprintf(stderr, "\nName: ");        scanf("\n"); getline(&name, &read_buf, stdin);
 
      fprintf(stderr, "\nSubmitter: ");                getline(&submitter, &read_buf, stdin);
 
      fprintf(stderr, "\nEmail: ");                    getline(&email, &read_buf, stdin);
 
      fprintf(stderr, "\nPriority: ");                 scanf("%d", &priority);
 
      fprintf(stderr, "\nStart frame: ");              scanf("%d", &start_frame);
 
      fprintf(stderr, "\nEnd frame: ");                scanf("%d", &end_frame);
 
      fprintf(stderr, "\nWidth: ");                    scanf("%d", &width);
 
      fprintf(stderr, "\nHeight: ");                   scanf("%d", &height);
 
      prepare_distrenjob(&general_info, type, name, submitter, email, priority, start_frame, end_frame, width, height);
 
      break;
 
    case 5:
 
      fprintf(stderr, "\nJob number: ");
 
      scanf("%d", &jobnum);
 
      distrenjob_remove(&general_info, distrenjob_get(&general_info.head, jobnum));
 
      break;
 
    case 6:
 
      printAllJobnums(&general_info.head);
 
      break;
 
    case 7:
 
      fprintf(stderr, "\nHighest job number: %d", general_info.highest_jobnum);
 
      fprintf(stderr, "\nJobs in queue: %d", general_info.jobs_in_queue);
 
      fprintf(stderr, "\nTotal frames rendered: %d", general_info.total_frames_rendered);
 
      fprintf(stderr, "\nTimestamp: %lu", (long)general_info.timestamp);
 
      fprintf(stderr, "\nTotal priority pieces: %ld", general_info.total_priority_pieces);
 
      fprintf(stderr, "\nTotal render power: %ld\n", general_info.total_render_power);
 
      break;
 
    case 8:
 
      fprintf(stderr,"Goodbye.\n");
 
      return 0;
 
    default:
 
      fprintf(stderr, "Invalid input, please try again.\n");
 
    }
 
  }
 

	
 
  distrend_listen(general_info.config, &clients);
 
  /* This is called the "main loop" */
 
  while(!general_info.config->die)
 
    {
 
      int clientsays = 0; /*< temporary example variable, will be replaced when we can handle messages */
 

	
 
      distrend_accept(general_info.config, clients);
 

	
 
      /* Make the following code more event-driven */
 
      frame_watchdog(&general_info.head);
 

	
 

	
 
      struct frameset *frame;
 
      struct distrenjob *job;
 

	
 
      /* If the client is idle, must be modified for climbing through linked list of clients (client->clientnum) */
 
      if(clientstatus == CLIENTSTATUS_IDLE)
 
	{
 
	  int returnnum = find_jobframe(&general_info, &job, &frame); // Finds a frame to render
0 comments (0 inline, 0 general)