ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rholo4.c
Revision: 3.29
Committed: Tue May 13 17:58:33 2003 UTC (20 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 3.28: +1 -1 lines
Log Message:
Changed (char *) casts for memory copies to (void *) and other fixes

File Contents

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