ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/raypcalls.c
(Generate patch)

Comparing ray/src/rt/raypcalls.c (file contents):
Revision 2.6 by schorsch, Tue Mar 30 16:13:01 2004 UTC vs.
Revision 2.9 by greg, Mon Sep 20 16:26:58 2004 UTC

# Line 51 | Line 51 | static const char      RCSid[] = "$Id$";
51   *  Note the differences between this and the simpler ray_trace()
52   *  call.  In particular, the call may or may not return a value
53   *  in the passed ray structure.  Also, you need to call rayorigin()
54 < *  yourself, which is normally for you by ray_trace().  The
55 < *  great thing is that ray_pqueue() will trace rays faster in
54 > *  yourself, which is normally called for you by ray_trace().  The
55 > *  benefit is that ray_pqueue() will trace rays faster in
56   *  proportion to the number of CPUs you have available on your
57   *  system.  If the ray queue is full before the call, ray_pqueue()
58   *  will block until a result is ready so it can queue this one.
# Line 81 | Line 81 | static const char      RCSid[] = "$Id$";
81   *              ray_psend(&myRay);
82   *      }
83   *
84 < *  The ray_presult() and/or ray_pqueue() functions may then be
85 < *  called to read back the results.
84 > *  Note that it is a fatal error to call ra_psend() when
85 > *  ray_pnidle is zero.  The ray_presult() and/or ray_pqueue()
86 > *  functions may be called subsequently to read back the results.
87   *
88   *  When you are done, you may call ray_pdone(1) to close
89   *  all child processes and clean up memory used by Radiance.
# Line 99 | Line 100 | static const char      RCSid[] = "$Id$";
100   *  If you just want to reap children so that you can alter the
101   *  rendering parameters without reloading the scene, use the
102   *  ray_pclose(0) and ray_popen(nproc) calls to close
103 < *  then restart the child processes.
103 > *  then restart the child processes after the changes are made.
104   *
105   *  Note:  These routines are written to coordinate with the
106   *  definitions in raycalls.c, and in fact depend on them.
107   *  If you want to trace a ray and get a result synchronously,
108 < *  use the ray_trace() call to compute it in the parent process.
108 > *  use the ray_trace() call to compute it in the parent process
109 > *  This will not interfere with any subprocess calculations,
110 > *  but beware that a fatal error may end with a call to quit().
111   *
112   *  Note:  One of the advantages of using separate processes
113   *  is that it gives the calling program some immunity from
114   *  fatal rendering errors.  As discussed in raycalls.c,
115   *  Radiance tends to throw up its hands and exit at the
116   *  first sign of trouble, calling quit() to return control
117 < *  to the system.  Although you can avoid exit() with
117 > *  to the top level.  Although you can avoid exit() with
118   *  your own longjmp() in quit(), the cleanup afterwards
119   *  is always suspect.  Through the use of subprocesses,
120   *  we avoid this pitfall by closing the processes and
# Line 120 | Line 123 | static const char      RCSid[] = "$Id$";
123   *  of these calls, you can assume that the processes have
124   *  been cleaned up with a call to ray_close(), though you
125   *  will have to call ray_pdone() yourself if you want to
126 < *  free memory.  Obviously, you cannot continue rendering,
127 < *  but otherwise your process should not be compromised.
126 > *  free memory.  Obviously, you cannot continue rendering
127 > *  without risking further errors, but otherwise your
128 > *  process should not be compromised.
129   */
130  
131   #include <stdio.h>
# Line 464 | Line 468 | ray_popen(                     /* open the specified # processes */
468                  if (r_proc[ray_pnprocs].pid < 0)
469                          error(SYSTEM, "cannot fork child process");
470                  close(p1[0]); close(p0[1]);
471 +                /*
472 +                 * Close write stream on exec to avoid multiprocessing deadlock.
473 +                 * No use in read stream without it, so set flag there as well.
474 +                 */
475 +                fcntl(p1[1], F_SETFD, FD_CLOEXEC);
476 +                fcntl(p0[0], F_SETFD, FD_CLOEXEC);
477                  r_proc[ray_pnprocs].fd_send = p1[1];
478                  r_proc[ray_pnprocs].fd_recv = p0[0];
479                  r_proc[ray_pnprocs].npending = 0;
# Line 496 | Line 506 | ray_pclose(            /* close one or more child processes */
506                  ray_pnprocs--;
507                  close(r_proc[ray_pnprocs].fd_recv);
508                  close(r_proc[ray_pnprocs].fd_send);
509 <                while (wait(&status) != r_proc[ray_pnprocs].pid)
510 <                        ;
509 >                if (waitpid(r_proc[ray_pnprocs].pid, &status, 0) < 0)
510 >                        status = 127<<8;
511                  if (status) {
512                          sprintf(errmsg,
513                                  "rendering process %d exited with code %d",

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines