Back to index

radiance  4R0+20100331
Defines | Functions | Variables
rholo4.c File Reference
#include "rholo.h"
#include "rhdisp.h"
#include "rtprocess.h"
#include <sys/uio.h>
#include <string.h>

Go to the source code of this file.

Defines

#define HDSUF   ".hdi"
#define SLAVENAME   "slave"
#define FNONBLK   O_NONBLOCK

Functions

static void disp_flush (void)
static void disp_result (int type, int nbytes, char *p)
void disp_open (char *dname)
void disp_packet (register PACKHEAD *p)
int disp_check (int block)
int disp_close (void)

Variables

static const char RCSid [] = "$Id: rholo4.c,v 3.36 2004/01/01 11:21:55 schorsch Exp $"
static int inp_flags
static SUBPROC dpd
static FILE * dpout

Define Documentation

#define FNONBLK   O_NONBLOCK

Definition at line 22 of file rholo4.c.

#define HDSUF   ".hdi"

Definition at line 15 of file rholo4.c.

#define SLAVENAME   "slave"

Definition at line 18 of file rholo4.c.


Function Documentation

int disp_check ( int  block)

Definition at line 111 of file rholo4.c.

{
       MSGHEAD       msg;
       int    n;
       char   *buf = NULL;

       if (dpout == NULL)
              return(-1);
                                   /* flush display output */
       disp_flush();
                                   /* check read blocking */
       if (block != (inp_flags == 0)) {
              inp_flags = block ? 0 : FNONBLK;
              if (fcntl(dpd.r, F_SETFL, inp_flags) < 0)
                     goto fcntlerr;
       }
                                   /* read message header */
       n = read(dpd.r, (char *)&msg, sizeof(MSGHEAD));
       if (n != sizeof(MSGHEAD)) {
              if (n >= 0) {
                     dpout = NULL;
                     error(USER, "display process died");
              }
              if ((errno != EAGAIN) & (errno != EINTR))
                     goto readerr;
              return(2);           /* acceptable failure */
       }
       if (msg.nbytes) {           /* get the message body */
              if (msg.nbytes < 0)
                     error(INTERNAL, "anti-message from display process");
              buf = (char *)malloc(msg.nbytes);
              if (buf == NULL)
                     error(SYSTEM, "out of memory in disp_check");
              if (inp_flags != 0 && fcntl(dpd.r, F_SETFL, inp_flags=0) < 0)
                     goto fcntlerr;
              if (readbuf(dpd.r, buf, msg.nbytes) != msg.nbytes)
                     goto readerr;
       }
       switch (msg.type) {         /* take appropriate action */
       case DR_BUNDLE:             /* new bundle to calculate */
              if (msg.nbytes != sizeof(PACKHEAD))
                     error(INTERNAL, "bad DR_BUNDLE from display process");
              bundle_set(BS_ADD, (PACKHEAD *)buf, 1);
              break;
       case DR_NEWSET:             /* new calculation set */
              if (msg.nbytes % sizeof(PACKHEAD))
                     error(INTERNAL, "bad DR_NEWSET from display process");
              if (msg.nbytes)
                     disp_result(DS_STARTIMM, 0, NULL);
              bundle_set(BS_NEW, (PACKHEAD *)buf, msg.nbytes/sizeof(PACKHEAD));
              if (msg.nbytes) {
                     disp_result(DS_ENDIMM, 0, NULL);
                     disp_flush();
              }
              break;
       case DR_ADDSET:             /* add to calculation set */
              if (!msg.nbytes)
                     break;
              if (msg.nbytes % sizeof(PACKHEAD))
                     error(INTERNAL, "bad DR_ADDSET from display process");
              disp_result(DS_STARTIMM, 0, NULL);
              bundle_set(BS_ADD, (PACKHEAD *)buf, msg.nbytes/sizeof(PACKHEAD));
              disp_result(DS_ENDIMM, 0, NULL);
              disp_flush();
              break;
       case DR_ADJSET:             /* adjust calculation set members */
              if (!msg.nbytes)
                     break;
              if (msg.nbytes % sizeof(PACKHEAD))
                     error(INTERNAL, "bad DR_ADJSET from display process");
              disp_result(DS_STARTIMM, 0, NULL);
              bundle_set(BS_ADJ, (PACKHEAD *)buf, msg.nbytes/sizeof(PACKHEAD));
              disp_result(DS_ENDIMM, 0, NULL);
              disp_flush();
              break;
       case DR_DELSET:             /* delete from calculation set */
              if (!msg.nbytes)
                     break;
              if (msg.nbytes % sizeof(PACKHEAD))
                     error(INTERNAL, "bad DR_DELSET from display process");
              bundle_set(BS_DEL, (PACKHEAD *)buf, msg.nbytes/sizeof(PACKHEAD));
              break;
       case DR_VIEWPOINT:   /* set target eye position */
              if (msg.nbytes != sizeof(VIEWPOINT))
                     error(INTERNAL, "bad DR_VIEWPOINT from display process");
              myeye = *((VIEWPOINT *)buf);
              break;
       case DR_ATTEN:              /* block for priority request */
              if (msg.nbytes)
                     error(INTERNAL, "bad DR_ATTEN from display process");
                                   /* send acknowledgement */
              disp_result(DS_ACKNOW, 0, NULL);
              return(disp_check(1));      /* block on following request */
       case DR_KILL:        /* kill computation process(es) */
              if (msg.nbytes)
                     error(INTERNAL, "bad DR_KILL from display process");
              if (nprocs > 0)
                     done_rtrace();
              else
                     error(WARNING, "no rtrace process to kill");
              break;
       case DR_RESTART:     /* restart computation process(es) */
              if (msg.nbytes)
                     error(INTERNAL, "bad DR_RESTART from display process");
              if (ncprocs > nprocs)
                     new_rtrace();
              else if (nprocs > 0)
                     error(WARNING, "rtrace already runnning");
              else
                     error(WARNING, "holodeck not open for writing");
              break;
       case DR_CLOBBER:     /* clobber holodeck */
              if (msg.nbytes)
                     error(INTERNAL, "bad DR_CLOBBER from display process");
              if ((force <= 0) | (ncprocs <= 0))
                     error(WARNING, "request to clobber holodeck denied");
              else {
                     error(WARNING, "clobbering holodeck contents");
                     hdclobber(NULL);
              }
              break;
       case DR_SHUTDOWN:    /* shut down program */
              if (msg.nbytes)
                     error(INTERNAL, "bad DR_SHUTDOWN from display process");
              return(0);           /* zero return signals shutdown */
       case DR_NOOP:        /* do nothing */
              break;
       default:
              error(INTERNAL, "unrecognized request from display process");
       }
       if (msg.nbytes)                    /* clean up */
              free(buf);
       return(1);                  /* normal return value */
fcntlerr:
       error(SYSTEM, "cannot change display blocking mode");
readerr:
       error(SYSTEM, "error reading from display process");
       return -1; /* pro forma return */
}

Here is the call graph for this function:

Here is the caller graph for this function:

int disp_close ( void  )

Definition at line 255 of file rholo4.c.

{
       if (dpout == NULL)
              return(-1);
       myeye.rng = 0;
       disp_result(DS_SHUTDOWN, 0, NULL);
       fclose(dpout);
       dpout = NULL;
       return(dpd.running ? close_process(&dpd) : 0);

}

Here is the call graph for this function:

Here is the caller graph for this function:

static void disp_flush ( void  ) [static]

Definition at line 292 of file rholo4.c.

{
       if (fflush(dpout) < 0)
              error(SYSTEM, "error writing to the display process");
}

Here is the call graph for this function:

Here is the caller graph for this function:

void disp_open ( char *  dname)

Definition at line 34 of file rholo4.c.

{
       char   buf[sizeof(HDGRID)+512], fd0[8], fd1[8], *cmd[5], *sfn;
       int    i, n, len;

       if (!strcmp(dname, SLAVENAME)) {
              dpd.r = 0;           /* read from stdin */
              dpout = stdout;             /* write to stdout */
              dpd.running = 0; /* we're the slave procees */
       } else {
                                   /* get full display program name */
#ifdef DEVPATH
              sprintf(buf, "%s/%s%s", DEVPATH, dname, HDSUF);
#else
              sprintf(buf, "dev/%s%s", dname, HDSUF);
#endif
                                   /* dup stdin and stdout */
              if (readinp)
                     sprintf(fd0, "%d", dup(0));
              else
                     strcpy(fd0, "-1");
              sprintf(fd1, "%d", dup(1));
                                   /* start the display process */
              cmd[0] = buf;
              cmd[1] = froot; cmd[2] = fd1; cmd[3] = fd0;
              cmd[4] = NULL;
              i = open_process(&dpd, cmd);
              if (i <= 0)
                     error(USER, "cannot start display process");
              if ((dpout = fdopen(dpd.w, "w")) == NULL)
                     error(SYSTEM, "problem opening display pipe");
                                   /* close dup'ed stdin and stdout */
              if (readinp)
                     close(atoi(fd0));
              close(atoi(fd1));
       }
       dpd.w = -1;          /* causes ignored error in close_process() */
       inp_flags = 0;
                            /* check if outside */
       if (vdef(OBSTRUCTIONS) && vbool(OBSTRUCTIONS))
              disp_result(DS_OUTSECT, 0, NULL);
                            /* send eye separation if specified */
       if (vdef(EYESEP)) {
              sprintf(buf, "%.9e", vflt(EYESEP));
              disp_result(DS_EYESEP, strlen(buf)+1, buf);
       }
                            /* write out hologram grids & octrees */
       for (i = 0; hdlist[i] != NULL; i++) {
              memcpy(buf, (void *)hdlist[i], sizeof(HDGRID));
              len = sizeof(HDGRID);
              n = vdef(GEOMETRY);
              sfn = i<n ? nvalue(GEOMETRY,i) :
                            n ? nvalue(GEOMETRY,n-1) : vval(OCTREE);
              strcpy(buf+len, sfn);
              len += strlen(sfn) + 1;
              n = vdef(PORTS);
              sfn = i<n ? nvalue(PORTS,i) : n ? nvalue(PORTS,n-1) : "";
              strcpy(buf+len, sfn);
              len += strlen(sfn) + 1;
              disp_result(DS_ADDHOLO, len, buf);
       }
       disp_flush();
}

Here is the call graph for this function:

Here is the caller graph for this function:

void disp_packet ( register PACKHEAD p)

Definition at line 102 of file rholo4.c.

{
       disp_result(DS_BUNDLE, packsiz(p->nr), (char *)p);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void disp_result ( int  type,
int  nbytes,
char *  p 
) [static]

Definition at line 269 of file rholo4.c.

{
       MSGHEAD       msg;
                                   /* consistency checks */
#ifdef DEBUG
       if (nbytes < 0 || nbytes > 0 & p == NULL)
              error(CONSISTENCY, "bad buffer handed to disp_result");
#endif
       if (dpout == NULL)
              return;
       msg.type = type;
       msg.nbytes = nbytes;
       fwrite((char *)&msg, sizeof(MSGHEAD), 1, dpout);
       if (nbytes > 0)
              fwrite(p, 1, nbytes, dpout);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

SUBPROC dpd [static]

Definition at line 26 of file rholo4.c.

FILE* dpout [static]

Definition at line 27 of file rholo4.c.

int inp_flags [static]

Definition at line 25 of file rholo4.c.

const char RCSid[] = "$Id: rholo4.c,v 3.36 2004/01/01 11:21:55 schorsch Exp $" [static]

Definition at line 2 of file rholo4.c.