ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/persist.c
Revision: 2.13
Committed: Thu Jul 4 09:54:59 1996 UTC (27 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.12: +16 -6 lines
Log Message:
made it so alarm signal causes quiet termination in persist mode
fixed minor synchronization problem by adding sleep() call.  (I hope!)

File Contents

# Content
1 /* Copyright (c) 1996 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * Routines for persistent rtrace and rpict processes.
9 */
10
11 #include "standard.h"
12
13 #ifdef F_SETLKW
14
15 #include "paths.h"
16 #include <signal.h>
17 #include <sys/types.h>
18 #include <sys/stat.h>
19
20 #ifndef TIMELIM
21 #define TIMELIM (8*3600) /* time limit for holding pattern */
22 #endif
23
24 extern char *strcpy(), *index();
25
26 extern int headismine; /* boolean true if header belongs to me */
27
28 extern char *progname; /* global program name */
29
30 static char *persistfname = NULL; /* persist file name */
31 static int persistfd = -1; /* persist file descriptor */
32
33 static char inpname[TEMPLEN+1], outpname[TEMPLEN+1];
34
35
36 pfdetach() /* release persist (and header) resources */
37 {
38 if (persistfd >= 0)
39 close(persistfd);
40 persistfd = -1;
41 persistfname = NULL;
42 inpname[0] = '\0';
43 outpname[0] = '\0';
44 headismine = 0;
45 }
46
47
48 pfclean() /* clean up persist files */
49 {
50 if (persistfd >= 0)
51 close(persistfd);
52 if (persistfname != NULL)
53 unlink(persistfname);
54 if (inpname[0])
55 unlink(inpname);
56 if (outpname[0])
57 unlink(outpname);
58 }
59
60
61 pflock(lf) /* place or release exclusive lock on file */
62 int lf;
63 {
64 struct flock fls;
65
66 fls.l_type = lf ? F_WRLCK : F_UNLCK;
67 fls.l_whence = 0;
68 fls.l_start = 0L;
69 fls.l_len = 0L;
70 if (fcntl(persistfd, F_SETLKW, &fls) < 0)
71 error(SYSTEM, "cannot (un)lock persist file");
72 }
73
74
75 persistfile(pfn) /* open persist file and lock it */
76 char *pfn;
77 {
78 persistfd = open(pfn, O_WRONLY|O_CREAT|O_EXCL, 0644);
79 if (persistfd >= 0) {
80 persistfname = pfn;
81 pflock(1);
82 return;
83 }
84 /* file exists -- switch to i/o process */
85 persistfd = open(pfn, O_RDWR);
86 if (persistfd < 0) {
87 sprintf(errmsg, "cannot open persist file \"%s\"", pfn);
88 error(SYSTEM, errmsg);
89 }
90 pflock(1);
91 io_process(); /* never returns */
92 }
93
94
95 static int got_io;
96
97 static int sig_io() { got_io++; }
98
99 static int sig_alrm() { quit(0); }
100
101
102 pfhold() /* holding pattern for idle rendering process */
103 {
104 int (*oldalrm)();
105 char buf[512];
106 register int n;
107 /* close input and output descriptors */
108 close(fileno(stdin));
109 close(fileno(stdout));
110 /* create named pipes for input and output */
111 if (mknod(mktemp(strcpy(inpname,TEMPLATE)), S_IFIFO|0600, 0) < 0)
112 goto createrr;
113 if (mknod(mktemp(strcpy(outpname,TEMPLATE)), S_IFIFO|0600, 0) < 0)
114 goto createrr;
115 sprintf(buf, "%s %d\n%s\n%s\n", progname, getpid(), inpname, outpname);
116 if (lseek(persistfd, 0L, 0) < 0 || ftruncate(persistfd, 0L) < 0)
117 error(SYSTEM, "seek/truncate error on persist file");
118 n = strlen(buf);
119 if (write(persistfd, buf, n) < n)
120 error(SYSTEM, "error writing persist file");
121 /* wait TIMELIM for someone to signal us */
122 got_io = 0;
123 signal(SIGIO, sig_io);
124 oldalrm = (int (*)())signal(SIGALRM, sig_alrm);
125 alarm(TIMELIM);
126 pflock(0);
127 while (!got_io)
128 pause();
129 alarm(0);
130 signal(SIGALRM, oldalrm);
131 signal(SIGIO, SIG_DFL);
132 pflock(1);
133 /* someone wants us; reopen stdin and stdout */
134 if (freopen(inpname, "r", stdin) == NULL)
135 goto openerr;
136 if (freopen(outpname, "w", stdout) == NULL)
137 goto openerr;
138 unlink(inpname);
139 inpname[0] = '\0';
140 unlink(outpname);
141 outpname[0] = '\0';
142 return;
143 createrr:
144 error(SYSTEM, "cannot create named pipes in pfhold");
145 openerr:
146 error(SYSTEM, "cannot open named pipes in pfhold");
147 }
148
149
150 io_process() /* just act as conduits to and from actual process */
151 {
152 register char *cp;
153 register int nr, n;
154 char buf[512], *pfin, *pfout;
155 int pid;
156 /* load and close persist file */
157 sleep(5); /* helps synchronization */
158 nr = read(persistfd, buf, sizeof(buf)-1);
159 pfdetach();
160 if (nr <= 0)
161 error(SYSTEM, "cannot read persist file");
162 buf[nr] = '\0';
163 if ((cp = index(buf, ' ')) == NULL)
164 goto formerr;
165 *cp++ = '\0';
166 if ((pid = atoi(cp)) <= 0)
167 goto formerr;
168 if ((cp = index(cp, '\n')) == NULL)
169 goto formerr;
170 pfin = ++cp;
171 if ((cp = index(cp, '\n')) == NULL)
172 goto formerr;
173 *cp++ = '\0';
174 pfout = cp;
175 if ((cp = index(cp, '\n')) == NULL)
176 goto formerr;
177 *cp++ = '\0';
178 if (cp-buf != nr)
179 goto formerr;
180 if (strcmp(buf, progname)) {
181 sprintf(errmsg, "persist file for %s, not %s", buf, progname);
182 error(USER, errmsg);
183 }
184 /* wake up rendering process */
185 if (kill(pid, SIGIO) < 0)
186 error(SYSTEM, "cannot signal rendering process in io_process");
187 pid = fork(); /* fork i/o process */
188 if (pid < 0)
189 error(SYSTEM, "fork failed in io_process");
190 /* connect to appropriate pipe */
191 if (pid) { /* parent passes renderer output */
192 close(0);
193 if (open(pfout, O_RDONLY) != 0)
194 error(SYSTEM, "cannot open input pipe in io_process");
195 } else { /* child passes renderer input */
196 close(1);
197 if (open(pfin, O_WRONLY) != 1)
198 error(SYSTEM, "cannot open output pipe in io_process");
199 }
200 /* pass input to output */
201 /* read as much as we can, write all of it */
202 while ((nr = read(0, cp=buf, sizeof(buf))) > 0)
203 do {
204 if ((n = write(1, cp, nr)) <= 0)
205 goto writerr;
206 cp += n;
207 } while ((nr -= n) > 0);
208 if (nr < 0)
209 error(SYSTEM, "read error in io_process");
210 close(0); /* close input */
211 close(1); /* close output */
212 if (pid) /* parent waits for child */
213 wait(0);
214 exit(0); /* all done, exit (not quit!) */
215 formerr:
216 error(USER, "format error in persist file");
217 writerr:
218 error(SYSTEM, "write error in io_process");
219 }
220
221 #else
222
223 pfclean() {}
224
225 #endif