Changeset - 6e74651480a0
[Not reviewed]
default
0 2 0
Nathan Brink (binki) - 16 years ago 2010-01-23 15:58:57
ohnobinki@ohnopublishing.net
clean up struct distrenjob and distrenjob_new()
2 files changed with 20 insertions and 9 deletions:
0 comments (0 inline, 0 general)
src/server/distrenjob.c
Show inline comments
 
@@ -9,109 +9,115 @@
 
  (at your option) any later version.
 

	
 
  DistRen is distributed in the hope that it will be useful,
 
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
  GNU Affero General Public License for more details.
 

	
 
  You should have received a copy of the GNU Affero General Public License
 
  along with DistRen.  If not, see <http://www.gnu.org/licenses/>.
 
*/
 

	
 
#include "asprintf.h"
 
#include "distrenjob.h"
 
#include "slavefuncs.h"
 

	
 
#include <libxml/parser.h>
 
#include <libxml/tree.h>
 
#include <libxml/xmlwriter.h>
 

	
 
void distrenjob_free(struct distrenjob **distrenjob)
 
{
 
  struct distrenjob *dj;
 

	
 
  dj = *distrenjob;
 
  xmlFree(dj->name);
 
  xmlFree(dj->submitter);
 

	
 
  free(dj->frameset);
 

	
 
  free(dj);
 
  *distrenjob = NULL;
 
}
 

	
 
int distrenjob_new(struct distrenjob **distrenjob)
 
{
 
  struct distrenjob *dj;
 

	
 
  dj = malloc(sizeof(struct distrenjob));
 
  if(!dj)
 
    {
 
      /* try to catch code that doesn't respect return values
 
       faster: */
 
      *distrenjob = NULL;
 
      return 1;
 
    }
 
  *distrenjob = dj;
 

	
 
  dj->next = NULL;
 
  dj->jobnum = 0; /*< @todo there should be a central jobnum allocator and a way to save the maximum jobnumber allocated */
 
  dj->type = 1;
 
  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;
 

	
 
  df->output_format = (char *)NULL;
 
  dj->width = 0;
 
  dj->height = 0;
 

	
 
  dj->priority = 0;
 
  dj->completed_frames = 0;
 
  dj->assigned_frames = 0;
 
  dj->total_frames = 0;
 
  dj->prev_frame_index = -1;
 

	
 
  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->hibernate = 0;
 
  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)
 
    {
 
      fprintf(stderr, "_distrenjob_xml_readuint(): warning: unable to get property ``%s''\n",
 
	      propname);
 
      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;
 
@@ -235,96 +241,98 @@ int distrenjob_unserialize(struct distre
 
  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
 

	
 
  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);
 
  xmlTextWriterWriteAttribute(writer, (xmlChar *)"output_format", (xmlChar *)job->output_format);
 
  
 

	
 
  /**
 
     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)
src/server/distrenjob.h
Show inline comments
 
/*
 
  Copyright 2009 Nathan Phillip Brink, Ethan Zonca, Matthew Orlando
 

	
 
  This file is a part of DistRen.
 

	
 
  DistRen is free software: you can redistribute it and/or modify
 
  it under the terms of the GNU Affero General Public License as published by
 
  the Free Software Foundation, either version 3 of the License, or
 
  (at your option) any later version.
 

	
 
  DistRen is distributed in the hope that it will be useful,
 
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
  GNU Affero General Public License for more details.
 

	
 
  You should have received a copy of the GNU Affero General Public License
 
  along with DistRen.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
*/
 

	
 
#ifndef _DISTREN_DISTRENJOB_H
 
#define _DISTREN_DISTRENJOB_H
 

	
 
/**
 
   This file stores the distrenjob and frameset structs and prototypes for some functions to manipulate/use these.
 
 */
 

	
 
#include <time.h> /*< clock_t, time_t */
 

	
 
typedef unsigned int jobnum_t;
 

	
 
/**
 
   Stores Blender Job Info
 
*/
 
struct distrenjob
 
{
 
  struct distrenjob *next; /*< next will be NULL unless if there is another distrenjob */
 
  jobnum_t jobnum;
 
  short int type; /*< 1:Blender, 2:something else */
 
  char *name;
 
  char *submitter;
 
  jobnum_t jobnum;
 

	
 
  char *output_format; /*< currently is the file extension of the request output format. @todo make this mime-type based/not a string */
 
  unsigned int width; /*< width in pixels of the frames to be rendered */
 
  unsigned int height; /*< height in pixels of the frames to be rendered */
 

	
 
  unsigned int priority;  /*< 1 is lowest, 10 is highest, 0 means the job is done */
 
  unsigned int completed_frames; /*< number of completed frames for stats/etc */
 
  unsigned int assigned_frames; /*< number of assigned frames (that are not yet completed) for stats/etc */
 
  unsigned int total_frames; /*< how many frames are in the animation for stats/etc (unassigned frames) */
 
  int prev_frame_index; /*< the position in the array of the last frame that was assigned */
 

	
 
  time_t total_render_time; /*< total seconds of time spent on all the completed frames */
 
  unsigned long int assigned_render_power;
 
  unsigned int watchdog_forgiveness; /*< how many seconds 'til the frame is re-assigned (if client computer crashes etc); */
 
  short int hibernate; /*< @todo DOCUMENT THIS */
 
  int prev_frame_index; /*< the position in the array of the last frame that was assigned */
 
  time_t total_render_time; /*< total seconds of time spent on all the completed frames */
 
  char *output_format; /*< currently is the file extension of the request output format. @todo make this mime-type based/not a string */
 
  unsigned long int assigned_render_power;
 
  struct frameset *frameset;
 
};
 

	
 

	
 

	
 
/**
 
   Frameset Structure
 
*/
 
enum framesetstatus
 
  {
 
    FRAMESETSTATUS_CANCELED, /*< The use has canceled this frame */
 
    FRAMESETSTATUS_UNASSIGNED, /*< The frame has not been assigned */
 
    FRAMESETSTATUS_ASSIGNED, /*< The frame has been assigned */
 
    FRAMESETSTATUS_DONE /*< The frame has completed rendering and the slave has returned the product to me */
 
  };
 

	
 
struct frameset {
 
  int num; /*< frame number to render */
 
  char slave_name; /*< user that frame is assigned to */
 
  enum framesetstatus status; /*< status of frame, 0= unassigned, 1= taken, 2= done */
 
  clock_t start_time; /*< time the frame was started */
 
};
 

	
 
/*
 
  related functions
 
*/
 

	
 
/**
 

	
 
   @param distrenjob the address where we will store the pointer of a malloc()ed
 
   distrenjob struct.
 
   @param pathtoxml filename/pathname of the xml file to be read into a distrenjob struct
 
 */
 
int distrenjob_unserialize(struct distrenjob **distrenjob, char *pathtoxml);
 

	
 
/**
 
   serialize a distrenjob into XML
 
   @param distrenjob the address where we will store the pointer of a malloc()ed
 
   distrenjob struct.
 
   @param xmloutput filename/pathname of the xml file to be written
 
 */
 
int distrenjob_serialize(struct distrenjob *distrenjob, char *xmloutputpath);
 

	
 

	
 
/**
 
   support function for distrenjob_unserialize() to help cleaning up a
 
   struct distrenjob when it is incompletely initialized.
 
   Also acts as a general-purpose struct distrenjob free()er ;-)
0 comments (0 inline, 0 general)