--- ray/src/rt/raypcalls.c 2020/06/16 17:58:11 2.34 +++ ray/src/rt/raypcalls.c 2024/08/21 20:42:20 2.40 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: raypcalls.c,v 2.34 2020/06/16 17:58:11 greg Exp $"; +static const char RCSid[] = "$Id: raypcalls.c,v 2.40 2024/08/21 20:42:20 greg Exp $"; #endif /* * raypcalls.c - interface for parallel rendering using Radiance @@ -158,8 +158,6 @@ static const char RCSid[] = "$Id: raypcalls.c,v 2.34 2 #endif #endif -extern char *shm_boundary; /* boundary of shared memory */ - int ray_pnprocs = 0; /* number of child processes */ int ray_pnidle = 0; /* number of idle children */ @@ -217,7 +215,7 @@ ray_pflush(void) /* send queued rays to idle childre continue; /* smuggle set size in crtype */ r_queue[sfirst].crtype = n; - nw = writebuf(r_proc[i].fd_send, (char *)&r_queue[sfirst], + nw = writebuf(r_proc[i].fd_send, &r_queue[sfirst], sizeof(RAY)*n); if (nw != sizeof(RAY)*n) return(-1); /* write error */ @@ -348,7 +346,7 @@ getready: /* any children waiting for us? */ error(CONSISTENCY, "buffer shortage in ray_presult()"); /* read rendered ray data */ - n = readbuf(r_proc[pn].fd_recv, (char *)&r_queue[r_recv_next], + n = readbuf(r_proc[pn].fd_recv, &r_queue[r_recv_next], sizeof(RAY)*r_proc[pn].npending); if (n > 0) { r_recv_next += n/sizeof(RAY); @@ -388,10 +386,7 @@ ray_pdone( /* reap children and free data */ { ray_pclose(0); /* close child processes */ - if (shm_boundary != NULL) { /* clear shared memory boundary */ - free((void *)shm_boundary); - shm_boundary = NULL; - } + cow_doneshare(); /* clear shared memory boundary */ ray_done(freall); /* free rendering data */ } @@ -435,7 +430,7 @@ ray_pchild( /* process rays (never returns) */ rayvalue(&r_queue[i]); } /* write back our results */ - i = writebuf(fd_out, (char *)r_queue, sizeof(RAY)*n); + i = writebuf(fd_out, r_queue, sizeof(RAY)*n); if (i != sizeof(RAY)*n) error(SYSTEM, "write error in ray_pchild()"); } @@ -456,13 +451,10 @@ ray_popen( /* open the specified # processes */ nadd = MAX_NPROCS - ray_pnprocs; if (nadd <= 0) return; + if (nobjects <= 0) + error(CONSISTENCY, "ray_popen() called before scene loaded"); ambsync(); /* load any new ambient values */ - if (shm_boundary == NULL) { /* first child process? */ - preload_objs(); /* preload auxiliary data */ - /* set shared memory boundary */ - shm_boundary = (char *)malloc(16); - strcpy(shm_boundary, "SHM_BOUNDARY"); - } + cow_memshare(); /* copy-on-write shared memory */ fflush(NULL); /* clear pending output */ samplestep = ray_pnprocs + nadd; while (nadd--) { /* fork each new process */ @@ -510,20 +502,25 @@ ray_pclose( /* close one or more child processes */ static int inclose = 0; RAY res; int i, status = 0; + /* check no child / in child */ + if (ray_pnprocs <= 0) + return; /* check recursion */ if (inclose) return; inclose++; - /* check no child / in child */ - if (ray_pnprocs <= 0) - return; /* check argument */ if ((nsub <= 0) | (nsub > ray_pnprocs)) nsub = ray_pnprocs; /* clear our ray queue */ + i = r_send_next; + r_send_next = 0; while (ray_presult(&res,0) > 0) - ; - r_send_next = 0; /* hard reset in case of error */ + ++i; + if (i) { + sprintf(errmsg, "dropped %d rays in ray_pclose()", i); + error(WARNING, errmsg); + } r_recv_first = r_recv_next = RAYQLEN; /* close send pipes */ for (i = ray_pnprocs-nsub; i < ray_pnprocs; i++) @@ -537,6 +534,10 @@ ray_pclose( /* close one or more child processes */ for (i = 0; i < nsub; ) { int j, mystatus; RT_PID pid = wait(&mystatus); + if (pid < 0) { + status = 127<<8; + break; + } for (j = ray_pnprocs-nsub; j < ray_pnprocs; j++) if (r_proc[j].pid == pid) { if (mystatus)