Changeset - 71f0379b39de
[Not reviewed]
tip default
0 6 0
Nathan Brink (binki) - 15 years ago 2010-10-09 11:29:35
ohnobinki@ohnopublishing.net
Renice execio's newly spawned processes. Fixes bug 8.
6 files changed with 30 insertions and 12 deletions:
0 comments (0 inline, 0 general)
configure.ac
Show inline comments
 
@@ -27,24 +27,27 @@ AC_PROG_LIBTOOL
 
AM_INIT_AUTOMAKE([gnu dist-bzip2 subdir-objects -Wall])
 
AM_PROG_CC_C_O
 

	
 
dnl these macros force the refered to types to be available without me
 
dnl writing my own magic :-)
 
AC_TYPE_PID_T
 
AC_TYPE_SIZE_T
 

	
 
AC_TYPE_UINT8_T
 
AC_TYPE_UINT16_T
 
AC_TYPE_UINT32_T
 

	
 
dnl execio has a nice() call but it's not vital to our operation
 
AC_CHECK_FUNCS([nice])
 

	
 
dnl selective compilation
 
dnl For now, this is only left for when the C-based client is
 
dnl reintroducded.
 
AC_ARG_ENABLE([server],
 
	[AS_HELP_STRING([--disable-server],[Don't build the distren server])],
 
	[enable_server=$enableval],
 
	[enable_server=yes])
 
AM_CONDITIONAL([ENABLE_SERVER],
 
	[test "x$enable_server" = "xyes"])
 

	
 
dnl package dependencies:
 

	
src/common/execio.c
Show inline comments
 
@@ -23,25 +23,25 @@
 

	
 
#include <unistd.h>
 
#include <sys/types.h>
 
#ifndef _WIN32
 
#include <sys/wait.h>
 
#endif
 
#include <signal.h>
 
#include <fcntl.h>
 
#include <stdio.h>
 
#include <stdlib.h>
 
#include <errno.h>
 

	
 
int execio_open(struct execio **rem, const char *progname, char *const argv[])
 
int execio_open(struct execio **rem, const char *progname, char *const argv[], int nice_incr)
 
{
 
  /* pipe used to write to child */
 
  int pipe_write[2];
 
  /* pipe used to read from child */
 
  int pipe_read[2];
 

	
 
  pid_t child;
 

	
 
  /* for wait(2) if needed */
 
  int childstatus;
 
  
 
  int counter;
 
@@ -90,24 +90,29 @@ int execio_open(struct execio **rem, con
 
	}
 
      (*rem)->pipe_write = pipe_write[1];
 
      (*rem)->pipe_read = pipe_read[0];
 
      (*rem)->state = 0;
 
      (*rem)->child = child;
 
      
 
      return 0;
 
    }
 
  
 
  /* child */
 
  else
 
    {
 
#ifdef HAVE_NICE
 
      /* lower the nice value */
 
      nice(nice_incr);
 
#endif
 

	
 
      /* close unused pipes */
 
      close(pipe_write[1]);
 
      close(pipe_read[0]);
 

	
 
      /*
 
	reset stdin, stdout, and stderr to the appropriate files. OK, not stderr :-) 
 
      */
 
      dup2(pipe_read[1], STDOUT_FILENO);
 
      dup2(pipe_write[0], STDIN_FILENO);
 
      /*
 
	close the fds that were dup'd
 
       */
 
@@ -153,25 +158,25 @@ int _execio_checkpid(struct execio *eio)
 
  
 
#ifdef _WIN32
 
  waitpid(eio->child, &childstatus, 0);
 
#else
 
  waitpid(eio->child, &childstatus, WNOHANG);
 
#endif
 
  /* perror()? */
 

	
 
  return WIFEXITED(childstatus);
 
}
 

	
 

	
 
int execio_read(struct execio *eio, const void *buf, size_t len, size_t *bytesread)
 
int execio_read(struct execio *eio, void *buf, size_t len, size_t *bytesread)
 
{
 
  ssize_t ret;
 
  /*
 
    TODO: detect NULL eio? 
 
    TODO: errno?
 
    update status of eio for execio_status/to be able to cleanup subproc??
 

	
 
    whenever read() returns 0, it means EOF
 
   */
 
  
 
  ret = read(eio->pipe_read, buf, len);
 
  if(ret == -1)
src/common/execio.h
Show inline comments
 
@@ -35,35 +35,45 @@ enum execio_state
 

	
 
struct execio
 
{
 
  int pipe_write;
 
  int pipe_read;
 

	
 
  enum execio_state state;
 

	
 
  pid_t child;
 
};
 

	
 
/**
 
  runs progname with the arguments in argv. argv must be null terminated!!!!!!!!!
 

	
 
  returns nonzero return on error
 
 * \brief
 
 *   runs progname with the arguments in argv. argv must be null terminated!!!!!!!!!
 
 *
 
 * \param eio
 
 *   Where to store the pointer to the execio handle.
 
 * \param progname
 
 *   The name of the program to execute at the system's shell.
 
 * \param argv
 
 *   The NULL-terminated list of arguments to send to the subcommand.
 
 * \param nice_incr
 
 *   The amount to increase the subprogram's nice value by. See nice(3p).
 
 * \return
 
 *   nonzero return on error
 
*/
 
int execio_open(struct execio **eio, const char *progname, char *const argv[]);
 
int execio_open(struct execio **eio, const char *progname, char *const argv[], int nice_incr);
 

	
 
/**
 
   doesn't block,
 
   returns 0 on success, 1 on failure
 
*/
 
int execio_read(struct execio *eio, const void *buf, size_t len, size_t *bytesread);
 
int execio_read(struct execio *eio, void *buf, size_t len, size_t *bytesread);
 
int execio_write(struct execio *eio, const void *buf, size_t len, size_t *byteswritten);
 

	
 
/**
 
  use this function to determine if the using program should keep trying to read/write
 

	
 
  @todo is this function good enough/necessary?
 
 */
 
enum execio_state execio_state(struct execio *eio);
 

	
 
/**
 
   Closes an execio session.
 
   @return nonzero on error 
src/common/remoteio.c
Show inline comments
 
@@ -586,25 +586,25 @@ int _remoteio_ssh_open(struct remoteio *
 
{
 
  char *userhost;
 
  char *sshargs[] = {rem->opts->ssh_command, NULL /* userhost */, "distrend", "-d", (char *)NULL};
 

	
 
  int rtn;
 

	
 
  if(server->username)
 
    _distren_asprintf(&userhost, "%s@%s", server->username, server->hostname);
 
  else
 
    userhost = strdup(server->hostname);
 
  sshargs[1] = userhost;
 

	
 
  rtn = execio_open( &rem->execio, "ssh", sshargs);
 
  rtn = execio_open( &rem->execio, "ssh", sshargs, 0);
 
  if(rtn)
 
    {
 
      fprintf(stderr, "error opening remoteio channel to ssh userhost ``%s''\n" , userhost);
 
      free(userhost);
 
      return 1;
 
    }
 
  free(userhost);
 
  
 
  return 0;
 
}
 

	
 
int _remoteio_ssh_read(struct remoteio *rem, void *buf, size_t len, size_t *bytesread)
src/server/slavefuncs.c
Show inline comments
 
@@ -290,25 +290,25 @@ int exec_blender(char *input, char *outp
 
  char *cmd[] = { command, "-b", input, "-o", output, "-F", outputExt, "-f", frame_str, "-t", "0", (char *)NULL }; // arguments for blender
 

	
 
  if(DEBUG)
 
    fprintf(stderr,"Preparing to execute command: %s -b %s -o %s -f %s\n", command, input, output, frame_str);
 

	
 
  char buf[20];
 
  struct execio *testrem;
 
  size_t readlen;
 

	
 
  if(DEBUG)
 
    fprintf(stderr,"Executing: %s\n", frame_str);
 

	
 
  ret = execio_open(&testrem, command, cmd);
 
  ret = execio_open(&testrem, command, cmd, 10);
 
  if(ret)
 
    {
 
      fprintf(stderr, "Error running blender\n");
 
      return 1;
 
    }
 
  buf[19] = '\0';
 
  while(!execio_read(testrem, buf, 19, &readlen))
 
    {
 
       buf[readlen] = '\0';
 
       if(DEBUG)
 
         fprintf(stderr, "read \"%s\"\n", buf);
 
    }
 
@@ -718,25 +718,25 @@ int _web_getwork(int slavekey, char *sla
 
      *xres = atoi(tmp);
 

	
 
      tmp = strtok (NULL, ",");
 
      if(tmp == NULL)
 
        return 0; // no work
 
      *yres = atoi(tmp);
 

	
 
      tmp = strtok (NULL, ",");
 
      if(tmp == NULL)
 
        return 0; // no work
 
      *outputext = strdup(tmp);
 
      if(DEBUG)
 
        fprintf(stderr,"GETWORK Debug output - Job: %d | Frame: %d | Xres: %d | Yres: %d | Outformat: %s\n", *jobnum, *framenum, *xres, *yres, outputext);
 
        fprintf(stderr,"GETWORK Debug output - Job: %d | Frame: %d | Xres: %d | Yres: %d | Outformat: %s\n", *jobnum, *framenum, *xres, *yres, *outputext);
 

	
 
      // @FIXME: Setting outputext and serverversion = temp; will this cause issues as these are pointers to parts of the original temp var?
 

	
 
      // @TODO: This should be called every time, not just on fail.
 
      if(strcmp(PACKAGE_VERSION,serverversion)){
 
        fprintf(stderr,"Your distren package is out of date! Please acquire a newer version. (%s local vs %s remote)\n", PACKAGE_VERSION, serverversion);
 
        return 0;
 
      }
 
      if(DEBUG)
 
        fprintf(stderr,"Software versions: %s local vs %s remote\n", PACKAGE_VERSION, serverversion);
 

	
 

	
 
@@ -786,25 +786,25 @@ int slaveBenchmark(char *datadir, int *b
 
  // fprintf(stderr,"Preparing to execute command: %s -b %s -o %s -f %s\n", command, input, output, frame_str);
 
  fprintf(stderr,"Running benchmark...\n");
 

	
 
  long startTime;
 
  long endTime;
 

	
 
  time(&startTime);
 

	
 
  char buf[20];
 
  struct execio *testrem;
 
  size_t readlen;
 

	
 
  ret = execio_open(&testrem, command, cmd);
 
  ret = execio_open(&testrem, command, cmd, 10);
 
  if(ret)
 
    {
 
      fprintf(stderr, "Error executing blender\n");
 
      return 1;
 
    }
 

	
 
  buf[19] = '\0';
 
  while(!execio_read(testrem, buf, 19, &readlen))
 
    {
 
       buf[readlen] = '\0';
 
       fprintf(stderr, "read \"%s\"\n", buf);
 
    }
test/check_execio.c
Show inline comments
 
@@ -30,25 +30,25 @@ START_TEST (check_execio)
 
  char *echoargv[] = 
 
    {
 
      "echo",
 
      "test"
 
    };
 

	
 
  char inbuf[20];
 
  size_t bytesread;
 
  size_t pos;
 

	
 
  pos = 1;
 

	
 
  fail_unless(execio_open(&eio, echoargv[0], echoargv) == 0,
 
  fail_unless(execio_open(&eio, echoargv[0], echoargv, 0) == 0,
 
	      "execio_open failed");
 
  
 
  fail_unless(execio_read(eio, inbuf, sizeof(inbuf) - 1, &bytesread) == 0,
 
	      "error using execio_read\n");
 
  pos += bytesread;
 

	
 
  while (bytesread && pos < (sizeof(inbuf) - 1))
 
    {
 
      execio_read(eio, &inbuf[pos], sizeof(inbuf) - 1 - pos, &bytesread);
 
      pos += bytesread;
 
    }
 

	
0 comments (0 inline, 0 general)