Changeset - 1e4bbbad6d0b
[Not reviewed]
default
0 1 0
Nathan Brink (binki) - 16 years ago 2010-01-23 15:39:40
ohnobinki@ohnopublishing.net
reindent + debug msg
1 file changed with 4 insertions and 0 deletions:
0 comments (0 inline, 0 general)
src/server/distrenjob.c
Show inline comments
 
@@ -52,279 +52,283 @@ int distrenjob_new(struct distrenjob **d
 
      return 1;
 
    }
 
  *distrenjob = dj;
 

	
 
  dj->next = NULL;
 
  dj->name = (char *)NULL;
 
  dj->submitter = (char *)NULL;
 
  dj->jobnum = 0; /*< @todo there should be a central jobnum allocator and a way to save the maximum jobnumber allocated */
 
  dj->priority = 0;
 
  dj->width = 0;
 
  dj->height = 0;
 
  dj->completed_frames = 0;
 
  dj->assigned_frames = 0;
 
  dj->total_render_time = 0;
 
  dj->hibernate = 0;
 
  dj->prev_frame_index = -1;
 
  dj->assigned_render_power = 0;
 
  dj->watchdog_forgiveness = 3600; // initialize watchdog forgiveness at 1 hour
 
  dj->frameset = (struct frameset *)NULL; /*< @todo does frameset need to be initialized here? */
 

	
 
  return 0;
 
}
 

	
 
/**
 
   read an unsigned integer property from an xmlNode
 

	
 
   convenience function for distrenjob_unserialize()
 
   @param xmlnode may be NULL for convenience
 
   @return 0 on success, other on error
 
 */
 
int _distrenjob_xml_readuint(xmlNodePtr xmlnode, xmlChar *propname, unsigned int *num)
 
{
 
  xmlChar *string;
 

	
 
  if(!xmlnode)
 
    return 1;
 

	
 
  string = xmlGetProp(xmlnode, propname);
 
  if(!string)
 
    return 1;
 

	
 
  *num = (unsigned int)strtoul((char *)string, (char **)NULL, 10);
 
#ifndef NDEBUG
 
  fprintf(stderr, "_distrenjob_xml_readuint(%zx, \"%s\", *(%zx)=%u): read %s=\"%d\"\n",
 
	  (size_t)xmlnode, propname, (size_t)num, *num, propname, *num);
 
#endif
 

	
 
  xmlFree(string);
 
  return 0;
 
}
 

	
 
/**
 
   Loads a distrenjob that was serialized with distrenjob_serialize()
 

	
 
   @see distrenjob_serialize()
 
   @param pathtoxml path to XML file
 
   @param distrenjob will be set to a pointer
 
*/
 
int distrenjob_unserialize(struct distrenjob **distrenjob, char *pathtoxml)
 
{
 
  struct distrenjob *dj;
 
  struct frameset *fs;
 
  unsigned int start_frame;
 
  unsigned int end_frame;
 
  unsigned int counter;
 

	
 
  struct tm tm;
 

	
 
  xmlDocPtr xmldoc;
 
  xmlNodePtr xmlnode;
 
  xmlChar *xmlchar;
 

	
 
  xmlXPathContextPtr xmlxpathcontext;
 

	
 
  int tmp;
 

	
 
  if(distrenjob_new(distrenjob))
 
    return 1;
 
  dj = *distrenjob;
 

	
 
  xmldoc = xmlReadFile(pathtoxml, NULL, XML_PARSE_PEDANTIC);
 
  if(!xmldoc)
 
    {
 
      /**
 
	 @todo are we able to depend on libxml2's printed errors or
 
	 channel them into syslog output (eventually)? Currently,
 
	 this error is repetitious of a libxml2 error printed on stderr
 
	 for us.
 
       */
 
      fprintf(stderr, "error reading XML file ``%s''\n", pathtoxml);
 

	
 
      distrenjob_free(distrenjob);
 
      return 2;
 
    }
 

	
 
  xmlxpathcontext = xmlXPathNewContext(xmldoc);
 
  xmlnode = xml_quickxpath(xmlxpathcontext, (xmlChar *)"/job");
 
  if(!xmlnode)
 
    {
 
      distrenjob_free(distrenjob);
 
      return 3;
 
    }
 

	
 
  /*< @todo should we use xmlChar everywhere too? */
 
  dj->name = (char *)xmlGetProp(xmlnode, (xmlChar *)"name");
 
  if(!dj->name)
 
    {
 
      distrenjob_free(distrenjob);
 
      return 4;
 
    }
 

	
 
  /*< @todo validation needs to be done on usernames. e.g., currently, they shouldn't contain the '"' char  */
 
  dj->submitter = (char *)xmlGetProp(xmlnode, (xmlChar *)"submitter");
 
  if(!dj->submitter)
 
    {
 
      distrenjob_free(distrenjob);
 
      return 5;
 
    }
 
  tmp = _distrenjob_xml_readuint(xmlnode, (xmlChar *)"priority", &dj->priority);
 
  if(tmp)
 
    {
 
      distrenjob_free(distrenjob);
 
      return 6;
 
    }
 
  
 
  dj->output_format = (char *)xmlGetProp(xmlnode, (xmlChar *)"output_format");
 
  if(!dj->output_format)
 
    {
 
      distrenjob_free(distrenjob);
 

	
 
      return 6;
 
    }
 

	
 
  xmlnode = xml_quickxpath(xmlxpathcontext, (xmlChar *)"/job/resolution");
 
  tmp = _distrenjob_xml_readuint(xmlnode, (xmlChar *)"width"   , &dj->width   );
 
  tmp += _distrenjob_xml_readuint(xmlnode, (xmlChar *)"height"  , &dj->height  );
 

	
 
  xmlnode = xml_quickxpath(xmlxpathcontext, (xmlChar *)"/job/video");
 
  tmp += _distrenjob_xml_readuint(xmlnode, (xmlChar *)"start_frame", &start_frame);
 
  tmp += _distrenjob_xml_readuint(xmlnode, (xmlChar *)"end_frame", &end_frame);
 

	
 
  if(tmp)
 
    {
 
      fprintf(stderr, "distrenjob_unserialize(): error reading integer values from ``%s''\n",
 
	      pathtoxml);
 
      distrenjob_free(distrenjob);
 
      return 7;
 
    }
 

	
 
  /**
 
     total_render_time and watchdog stuff doesn't need error
 
     checking, just good defaults
 
  */
 
  xmlnode = xml_quickxpath(xmlxpathcontext, (xmlChar *)"/job/stats");
 
  dj->total_render_time = 0;
 
  xmlchar = xmlGetProp(xmlnode, (xmlChar *)"total_render_time");
 
  if(xmlchar)
 
    {
 
      if(strptime((char *)xmlchar, "%D %T", &tm))
 
	dj->total_render_time = mktime(&tm);
 
      xmlFree(xmlchar);
 
    }
 

	
 
  xmlnode = xml_quickxpath(xmlxpathcontext, (xmlChar *)"/job/watchdog");
 
  dj->watchdog_forgiveness = 3600;
 
  tmp =_distrenjob_xml_readuint(xmlnode, (xmlChar *)"forgiveness", &dj->watchdog_forgiveness);
 
  if(tmp)
 
    fprintf(stderr, "distrenjob_unserialize(): warning: watchdog forgiveness is unspecified in ``%s'', defaulting to 3600\n", pathtoxml);
 

	
 
  xmlXPathFreeContext(xmlxpathcontext);
 
  xmlFreeDoc(xmldoc);
 

	
 
  /**
 
     reconstruct the frameset
 
  */
 
  dj->total_frames = end_frame - start_frame + 1;
 
 dj->frameset = malloc(sizeof(struct frameset) * dj->total_frames);
 
 if(!dj->frameset)
 
   {
 
     fprintf(stderr, "OOM!\n");
 
     distrenjob_free(distrenjob);
 
     return 8;
 
   }
 
 fs = dj->frameset;
 
 for(counter = start_frame; counter <= end_frame; counter ++)
 
   {
 
     fs->num = counter;
 
     fs->status = FRAMESETSTATUS_UNASSIGNED; /*< @todo job partial completion and resumption support */
 

	
 
     fs ++;
 
   }
 

	
 
#ifndef NDEBUG
 
  fprintf(stderr, "distrenjob_unserialize(): finished loading ``%s''\n", pathtoxml);
 
#endif NDEBUG
 

	
 
  return 0;
 
}
 

	
 
int distrenjob_serialize(struct distrenjob *job, char *outfile)
 
{
 
  xmlTextWriterPtr writer;
 
  char *tmp;
 
  char *tmpfile;
 
  int tmprtn;
 

	
 
  /**
 
     transactional FS access for POSIX systems...
 
     (probably not implemented correctly)
 
   */
 
  _distren_asprintf(&tmpfile, "%s_", outfile);
 

	
 
  /* create xml document at the location tmp with no compression */
 
  writer = xmlNewTextWriterFilename(tmpfile, 0);
 
  xmlTextWriterStartDocument(writer, NULL, "utf-8", NULL);
 

	
 
  /**
 
     write distrenjob element and add its attributes */
 
  xmlTextWriterStartElement(writer, (xmlChar*)"job");
 
  xmlTextWriterWriteAttribute(writer, (xmlChar*)"name", (xmlChar*)job->name);
 
  xmlTextWriterWriteAttribute(writer, (xmlChar*)"submitter", (xmlChar*)job->submitter);
 
  _distren_asprintf(&tmp, "%d", job->priority);
 
  xmlTextWriterWriteAttribute(writer, (xmlChar*)"priority", (xmlChar*)tmp);
 
  free(tmp);
 

	
 
  /**
 
     write resolution element and add its attributes */
 
  xmlTextWriterStartElement(writer, (xmlChar*)"resolution");
 
  _distren_asprintf(&tmp, "%d", job->width);
 
  xmlTextWriterWriteAttribute(writer, (xmlChar*)"width", (xmlChar*)tmp);
 
  free(tmp);
 

	
 
  _distren_asprintf(&tmp, "%d", job->height);
 
  xmlTextWriterWriteAttribute(writer, (xmlChar*)"height", (xmlChar*)tmp);
 
  free(tmp);
 

	
 
  xmlTextWriterEndElement(writer);
 

	
 
  /**
 
     write video element and its attributes */
 
  xmlTextWriterStartElement(writer, (xmlChar*)"video");
 
  _distren_asprintf(&tmp, "%d", job->frameset[0].num);
 
  xmlTextWriterWriteAttribute(writer, (xmlChar*)"start_frame", (xmlChar*)tmp);
 
  free(tmp);
 

	
 
  _distren_asprintf(&tmp, "%d", job->frameset[(job->total_frames - 1)].num);
 
  xmlTextWriterWriteAttribute(writer, (xmlChar*)"end_fame", (xmlChar*)tmp);
 
  free(tmp);
 

	
 
  xmlTextWriterWriteAttribute(writer, (xmlChar*)"output_format", (xmlChar*)job->output_format);
 
  xmlTextWriterEndElement(writer);
 

	
 
  /**
 
     write watchdog forgiveness element */
 
  _distren_asprintf(&tmp, "%d", job->watchdog_forgiveness);
 
  xmlTextWriterWriteElement(writer, (xmlChar*)"wd_forgiveness", (xmlChar*)tmp);
 
  free(tmp);
 

	
 
  /**
 
     end document */
 
  xmlTextWriterEndDocument(writer);
 

	
 
  /**
 
     free writer and save xml file to disk */
 
  xmlFreeTextWriter(writer);
 

	
 
  /**
 
     This is the key to transactioanl POSIX
 
     FS programming.
 
   */
 
  tmprtn = rename(tmpfile, outfile);
 
  if(tmprtn == -1)
 
    {
 
      fprintf(stderr, "%s:%d: Error renaming ``%s'' to ``%s''\n",
 
	      __FILE__, __LINE__,
 
	      tmpfile, outfile);
 
      perror("rename");
 
      tmprtn = 1;
 
    }
 
  free(tmpfile);
 

	
 
  return tmprtn;
 
}
0 comments (0 inline, 0 general)