ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rholo4.c
Revision: 3.34
Committed: Mon Jul 21 22:30:18 2003 UTC (20 years, 9 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 3.33: +2 -2 lines
Log Message:
Eliminated copystruct() macro, which is unnecessary in ANSI.
Reduced ambiguity warnings for nested if/if/else clauses.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rholo4.c,v 3.33 2003/07/01 21:21:40 greg Exp $";
3 #endif
4 /*
5 * Holodeck display process communication
6 */
7
8 #include "rholo.h"
9 #include "rhdisp.h"
10 #include "rtprocess.h"
11 #include <sys/uio.h>
12 #include <string.h>
13
14 #ifndef HDSUF
15 #define HDSUF ".hdi"
16 #endif
17 #ifndef SLAVENAME
18 #define SLAVENAME "slave"
19 #endif
20
21 #ifndef FNONBLK
22 #define FNONBLK O_NONBLOCK
23 #endif
24
25 static int inp_flags;
26 static SUBPROC dpd;
27 static FILE *dpout;
28
29
30 disp_open(dname) /* open the named display driver */
31 char *dname;
32 {
33 char buf[sizeof(HDGRID)+512], fd0[8], fd1[8], *cmd[5], *sfn;
34 int i, n, len;
35
36 if (!strcmp(dname, SLAVENAME)) {
37 dpd.r = 0; /* read from stdin */
38 dpout = stdout; /* write to stdout */
39 dpd.running = 0; /* we're the slave procees */
40 } else {
41 /* get full display program name */
42 #ifdef DEVPATH
43 sprintf(buf, "%s/%s%s", DEVPATH, dname, HDSUF);
44 #else
45 sprintf(buf, "dev/%s%s", dname, HDSUF);
46 #endif
47 /* dup stdin and stdout */
48 if (readinp)
49 sprintf(fd0, "%d", dup(0));
50 else
51 strcpy(fd0, "-1");
52 sprintf(fd1, "%d", dup(1));
53 /* start the display process */
54 cmd[0] = buf;
55 cmd[1] = froot; cmd[2] = fd1; cmd[3] = fd0;
56 cmd[4] = NULL;
57 i = open_process(&dpd, cmd);
58 if (i <= 0)
59 error(USER, "cannot start display process");
60 if ((dpout = fdopen(dpd.w, "w")) == NULL)
61 error(SYSTEM, "problem opening display pipe");
62 /* close dup'ed stdin and stdout */
63 if (readinp)
64 close(atoi(fd0));
65 close(atoi(fd1));
66 }
67 dpd.w = -1; /* causes ignored error in close_process() */
68 inp_flags = 0;
69 /* check if outside */
70 if (vdef(OBSTRUCTIONS) && vbool(OBSTRUCTIONS))
71 disp_result(DS_OUTSECT, 0, NULL);
72 /* send eye separation if specified */
73 if (vdef(EYESEP)) {
74 sprintf(buf, "%.9e", vflt(EYESEP));
75 disp_result(DS_EYESEP, strlen(buf)+1, buf);
76 }
77 /* write out hologram grids & octrees */
78 for (i = 0; hdlist[i] != NULL; i++) {
79 memcpy(buf, (void *)hdlist[i], sizeof(HDGRID));
80 len = sizeof(HDGRID);
81 n = vdef(GEOMETRY);
82 sfn = i<n ? nvalue(GEOMETRY,i) :
83 n ? nvalue(GEOMETRY,n-1) : vval(OCTREE);
84 strcpy(buf+len, sfn);
85 len += strlen(sfn) + 1;
86 n = vdef(PORTS);
87 sfn = i<n ? nvalue(PORTS,i) : n ? nvalue(PORTS,n-1) : "";
88 strcpy(buf+len, sfn);
89 len += strlen(sfn) + 1;
90 disp_result(DS_ADDHOLO, len, buf);
91 }
92 disp_flush();
93 }
94
95
96 disp_packet(p) /* display a packet */
97 register PACKHEAD *p;
98 {
99 disp_result(DS_BUNDLE, packsiz(p->nr), (char *)p);
100 }
101
102
103 disp_check(block) /* check display process */
104 int block;
105 {
106 MSGHEAD msg;
107 int n;
108 char *buf = NULL;
109
110 if (dpout == NULL)
111 return(-1);
112 /* flush display output */
113 disp_flush();
114 /* check read blocking */
115 if (block != (inp_flags == 0)) {
116 inp_flags = block ? 0 : FNONBLK;
117 if (fcntl(dpd.r, F_SETFL, inp_flags) < 0)
118 goto fcntlerr;
119 }
120 /* read message header */
121 n = read(dpd.r, (char *)&msg, sizeof(MSGHEAD));
122 if (n != sizeof(MSGHEAD)) {
123 if (n >= 0) {
124 dpout = NULL;
125 error(USER, "display process died");
126 }
127 if (errno != EAGAIN & errno != EINTR)
128 goto readerr;
129 return(2); /* acceptable failure */
130 }
131 if (msg.nbytes) { /* get the message body */
132 if (msg.nbytes < 0)
133 error(INTERNAL, "anti-message from display process");
134 buf = (char *)malloc(msg.nbytes);
135 if (buf == NULL)
136 error(SYSTEM, "out of memory in disp_check");
137 if (inp_flags != 0 && fcntl(dpd.r, F_SETFL, inp_flags=0) < 0)
138 goto fcntlerr;
139 if (readbuf(dpd.r, buf, msg.nbytes) != msg.nbytes)
140 goto readerr;
141 }
142 switch (msg.type) { /* take appropriate action */
143 case DR_BUNDLE: /* new bundle to calculate */
144 if (msg.nbytes != sizeof(PACKHEAD))
145 error(INTERNAL, "bad DR_BUNDLE from display process");
146 bundle_set(BS_ADD, (PACKHEAD *)buf, 1);
147 break;
148 case DR_NEWSET: /* new calculation set */
149 if (msg.nbytes % sizeof(PACKHEAD))
150 error(INTERNAL, "bad DR_NEWSET from display process");
151 if (msg.nbytes)
152 disp_result(DS_STARTIMM, 0, NULL);
153 bundle_set(BS_NEW, (PACKHEAD *)buf, msg.nbytes/sizeof(PACKHEAD));
154 if (msg.nbytes) {
155 disp_result(DS_ENDIMM, 0, NULL);
156 disp_flush();
157 }
158 break;
159 case DR_ADDSET: /* add to calculation set */
160 if (!msg.nbytes)
161 break;
162 if (msg.nbytes % sizeof(PACKHEAD))
163 error(INTERNAL, "bad DR_ADDSET from display process");
164 disp_result(DS_STARTIMM, 0, NULL);
165 bundle_set(BS_ADD, (PACKHEAD *)buf, msg.nbytes/sizeof(PACKHEAD));
166 disp_result(DS_ENDIMM, 0, NULL);
167 disp_flush();
168 break;
169 case DR_ADJSET: /* adjust calculation set members */
170 if (!msg.nbytes)
171 break;
172 if (msg.nbytes % sizeof(PACKHEAD))
173 error(INTERNAL, "bad DR_ADJSET from display process");
174 disp_result(DS_STARTIMM, 0, NULL);
175 bundle_set(BS_ADJ, (PACKHEAD *)buf, msg.nbytes/sizeof(PACKHEAD));
176 disp_result(DS_ENDIMM, 0, NULL);
177 disp_flush();
178 break;
179 case DR_DELSET: /* delete from calculation set */
180 if (!msg.nbytes)
181 break;
182 if (msg.nbytes % sizeof(PACKHEAD))
183 error(INTERNAL, "bad DR_DELSET from display process");
184 bundle_set(BS_DEL, (PACKHEAD *)buf, msg.nbytes/sizeof(PACKHEAD));
185 break;
186 case DR_VIEWPOINT: /* set target eye position */
187 if (msg.nbytes != sizeof(VIEWPOINT))
188 error(INTERNAL, "bad DR_VIEWPOINT from display process");
189 myeye = *((VIEWPOINT *)buf);
190 break;
191 case DR_ATTEN: /* block for priority request */
192 if (msg.nbytes)
193 error(INTERNAL, "bad DR_ATTEN from display process");
194 /* send acknowledgement */
195 disp_result(DS_ACKNOW, 0, NULL);
196 return(disp_check(1)); /* block on following request */
197 case DR_KILL: /* kill computation process(es) */
198 if (msg.nbytes)
199 error(INTERNAL, "bad DR_KILL from display process");
200 if (nprocs > 0)
201 done_rtrace();
202 else
203 error(WARNING, "no rtrace process to kill");
204 break;
205 case DR_RESTART: /* restart computation process(es) */
206 if (msg.nbytes)
207 error(INTERNAL, "bad DR_RESTART from display process");
208 if (ncprocs > nprocs)
209 new_rtrace();
210 else if (nprocs > 0)
211 error(WARNING, "rtrace already runnning");
212 else
213 error(WARNING, "holodeck not open for writing");
214 break;
215 case DR_CLOBBER: /* clobber holodeck */
216 if (msg.nbytes)
217 error(INTERNAL, "bad DR_CLOBBER from display process");
218 if (force <= 0 | ncprocs <= 0)
219 error(WARNING, "request to clobber holodeck denied");
220 else {
221 error(WARNING, "clobbering holodeck contents");
222 hdclobber(NULL);
223 }
224 break;
225 case DR_SHUTDOWN: /* shut down program */
226 if (msg.nbytes)
227 error(INTERNAL, "bad DR_SHUTDOWN from display process");
228 return(0); /* zero return signals shutdown */
229 case DR_NOOP: /* do nothing */
230 break;
231 default:
232 error(INTERNAL, "unrecognized request from display process");
233 }
234 if (msg.nbytes) /* clean up */
235 free(buf);
236 return(1); /* normal return value */
237 fcntlerr:
238 error(SYSTEM, "cannot change display blocking mode");
239 readerr:
240 error(SYSTEM, "error reading from display process");
241 }
242
243
244 int
245 disp_close() /* close our display process */
246 {
247 int rval;
248
249 if (dpout == NULL)
250 return(-1);
251 myeye.rng = 0;
252 disp_result(DS_SHUTDOWN, 0, NULL);
253 fclose(dpout);
254 dpout = NULL;
255 return(dpd.running ? close_process(&dpd) : 0);
256
257 }
258
259
260 disp_result(type, nbytes, p) /* queue result message to display process */
261 int type, nbytes;
262 char *p;
263 {
264 MSGHEAD msg;
265 /* consistency checks */
266 #ifdef DEBUG
267 if (nbytes < 0 || nbytes > 0 & p == NULL)
268 error(CONSISTENCY, "bad buffer handed to disp_result");
269 #endif
270 if (dpout == NULL)
271 return;
272 msg.type = type;
273 msg.nbytes = nbytes;
274 fwrite((char *)&msg, sizeof(MSGHEAD), 1, dpout);
275 if (nbytes > 0)
276 fwrite(p, 1, nbytes, dpout);
277 }
278
279
280 disp_flush() /* flush output to display */
281 {
282 if (fflush(dpout) < 0)
283 error(SYSTEM, "error writing to the display process");
284 }