--- ray/src/util/rpiece.c 1992/08/09 12:12:48 2.8 +++ ray/src/util/rpiece.c 1992/08/09 23:05:17 2.11 @@ -15,6 +15,11 @@ static char SCCSid[] = "$SunId$ LBL"; #include "view.h" #include "resolu.h" + /* set the following to 0 to forgo forking */ +#ifndef MAXFORK +#define MAXFORK 3 /* allotment of duped processes */ +#endif + /* rpict command */ char *rpargv[128] = {"rpict", "-S", "1", "-x", "512", "-y", "512", "-pa", "1"}; int rpargc = 9; @@ -30,6 +35,7 @@ char *outfile = NULL; int outfd; long scanorig; int syncfd = -1; /* lock file descriptor */ +int nforked = 0; char *progname; int verbose = 0; @@ -117,7 +123,7 @@ char *argv[]; } init(argc, argv); rpiece(); - rval = cleanup(); + rval = cleanup(0); exit(rval); } @@ -238,22 +244,23 @@ int *xp, *yp; if (sscanf(buf, "%d %d", xp, yp) == 2) return(1); fprintf(stderr, "%s: input format error\n", progname); - exit(1); + exit(cleanup(1)); } int -cleanup() /* close rpict process and clean up */ +cleanup(rstat) /* close rpict process and clean up */ +int rstat; { - register int rpstat; + int status; free((char *)pbuf); fclose(torp); fclose(fromrp); - rpstat = close_process(rpd); - if (rpstat == -1) - rpstat = 0; - return(rpstat); + while (wait(&status) != -1) + if (rstat == 0) + rstat = status>>8 & 0xff; + return(rstat); } @@ -261,38 +268,39 @@ rpiece() /* render picture piece by piece */ { VIEW pview; int xorg, yorg; - + /* compute view parameters */ + copystruct(&pview, &ourview); + switch (ourview.type) { + case VT_PER: + pview.horiz = 2.*180./PI*atan( + tan(PI/180./2.*ourview.horiz)/hmult ); + pview.vert = 2.*180./PI*atan( + tan(PI/180./2.*ourview.vert)/vmult ); + break; + case VT_PAR: + case VT_ANG: + pview.horiz = ourview.horiz / hmult; + pview.vert = ourview.vert / vmult; + break; + case VT_HEM: + pview.horiz = 2.*180./PI*asin( + sin(PI/180./2.*ourview.horiz)/hmult ); + pview.vert = 2.*180./PI*asin( + sin(PI/180./2.*ourview.vert)/vmult ); + break; + default: + fprintf(stderr, "%s: unknown view type '-vt%c'\n", + progname, ourview.type); + exit(cleanup(1)); + } + /* render each piece */ while (nextpiece(&xorg, &yorg)) { - copystruct(&pview, &ourview); /* compute view for piece */ - switch (ourview.type) { - case VT_PER: - pview.horiz = 2.*180./PI*atan( - tan(PI/180./2.*ourview.horiz)/hmult ); - pview.vert = 2.*180./PI*atan( - tan(PI/180./2.*ourview.vert)/vmult ); - break; - case VT_PAR: - case VT_ANG: - pview.horiz = ourview.horiz / hmult; - pview.vert = ourview.vert / vmult; - break; - case VT_HEM: - pview.horiz = 2.*180./PI*asin( - sin(PI/180./2.*ourview.horiz)/hmult ); - pview.vert = 2.*180./PI*asin( - sin(PI/180./2.*ourview.vert)/vmult ); - break; - default: - fprintf(stderr, "%s: unknown view type '-vt%c'\n", - progname, ourview.type); - exit(1); - } - pview.hoff += xorg - 0.5*(hmult-1); - pview.voff += yorg - 0.5*(vmult-1); + pview.hoff = ourview.hoff + xorg - 0.5*(hmult-1); + pview.voff = ourview.voff + yorg - 0.5*(vmult-1); fputs(VIEWSTR, torp); fprintview(&pview, torp); putc('\n', torp); - fflush(torp); /* assign piece to rpict */ + fflush(torp); /* assigns piece to rpict */ putpiece(xorg, yorg); /* place piece in output */ if (verbose) { /* notify caller */ printf("%d %d done\n", xorg, yorg); @@ -302,32 +310,48 @@ rpiece() /* render picture piece by piece */ } +int putpiece(xpos, ypos) /* get next piece from rpict */ int xpos, ypos; { struct flock fls; + int pid, status; int hr, vr; register int y; /* check bounds */ if (xpos < 0 | ypos < 0 | xpos >= hmult | ypos >= vmult) { fprintf(stderr, "%s: requested piece (%d,%d) out of range\n", progname, xpos, ypos); - exit(1); + exit(cleanup(1)); } /* check header from rpict */ getheader(fromrp, NULL); - if (fscnresolu(&hr, &vr, fromrp) < 0 || hr != hres || vr != vres) { + if (fscnresolu(&hr, &vr, fromrp) < 0 || hr != hres | vr != vres) { fprintf(stderr, "%s: resolution mismatch from %s\n", progname, rpargv[0]); - exit(1); + exit(cleanup(1)); } /* load new piece into buffer */ for (y = 0; y < vr; y++) if (freadcolrs(pbuf+y*hr, hr, fromrp) < 0) { fprintf(stderr, "%s: read error from %s\n", progname, rpargv[0]); - exit(1); + exit(cleanup(1)); } +#if MAXFORK + /* fork so we don't slow rpict down */ + if ((pid = fork()) > 0) { + if (++nforked >= MAXFORK) { + wait(&status); /* reap a child */ + if (status) + exit(cleanup(status>>8 & 0xff)); + nforked--; + } + return(pid); + } +#else + pid = -1; /* no forking */ +#endif /* lock file section so NFS doesn't mess up */ fls.l_whence = 0; fls.l_len = (long)vres*hmult*hres*sizeof(COLR); @@ -337,22 +361,30 @@ int xpos, ypos; /* write new piece to file */ if (lseek(outfd, fls.l_start+(long)xpos*hres*sizeof(COLR), 0) == -1) goto seekerr; - for (y = 0; y < vr; y++) { - if (writebuf(outfd, (char *)(pbuf+y*hr), hr*sizeof(COLR)) != - hr*sizeof(COLR)) { - fprintf(stderr, "%s: write error on file \"%s\"\n", - progname, outfile); - exit(1); + if (hmult == 1) { + if (writebuf(outfd, (char *)pbuf, + vr*hr*sizeof(COLR)) != vr*hr*sizeof(COLR)) + goto writerr; + } else + for (y = 0; y < vr; y++) { + if (writebuf(outfd, (char *)(pbuf+y*hr), + hr*sizeof(COLR)) != hr*sizeof(COLR)) + goto writerr; + if (y < vr-1 && lseek(outfd, + (long)(hmult-1)*hr*sizeof(COLR), + 1) == -1) + goto seekerr; } - if (hmult != 1 && y < vr-1 && lseek(outfd, - (long)(hmult-1)*hr*sizeof(COLR), 1) == -1) - goto seekerr; + if (pid == -1) { /* fork failed */ + fls.l_type = F_UNLCK; /* release lock */ + fcntl(outfd, F_SETLKW, &fls); + return(0); } - /* unlock file section */ - fls.l_type = F_UNLCK; - fcntl(outfd, F_SETLKW, &fls); - return; + _exit(0); /* else exit child process (releasing lock) */ seekerr: fprintf(stderr, "%s: seek error on file \"%s\"\n", progname, outfile); - exit(1); + _exit(1); +writerr: + fprintf(stderr, "%s: write error on file \"%s\"\n", progname, outfile); + _exit(1); }