author | viric@llimona |
Sun, 25 Mar 2007 04:55:18 +0200 | |
changeset 23 | 96fcebb68510 |
parent 22 | afdc8410633f |
child 26 | 19d1bfdaa885 |
permissions | -rw-r--r-- |
8 | 1 |
#include <stdlib.h> |
2 |
#include <stdio.h> |
|
3 | 3 |
#include <assert.h> |
4 |
#include "msg.h" |
|
5 |
||
8 | 6 |
static enum |
7 |
{ |
|
19
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
8 |
FREE, /* No task is running */ |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
9 |
WAITING /* A task is running, and the server is waiting */ |
8 | 10 |
} state = FREE; |
11 |
||
3 | 12 |
struct Job |
13 |
{ |
|
14 |
int jobid; |
|
18 | 15 |
char *command; |
3 | 16 |
enum Jobstate state; |
19
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
17 |
int errorlevel; |
3 | 18 |
struct Job *next; |
22 | 19 |
char *output_filename; |
3 | 20 |
}; |
21 |
||
22 |
/* Globals */ |
|
23 |
static struct Job *firstjob = 0; |
|
19
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
24 |
static struct Job *first_finished_job = 0; |
3 | 25 |
static jobids = 0; |
26 |
||
5 | 27 |
static void send_list_line(int s, const char * str) |
28 |
{ |
|
29 |
struct msg m; |
|
30 |
int res; |
|
31 |
||
21 | 32 |
/* Message */ |
5 | 33 |
m.type = LIST_LINE; |
21 | 34 |
m.u.line_size = strlen(str) + 1; |
5 | 35 |
|
21 | 36 |
send_msg(s, &m); |
37 |
||
38 |
/* Send the line */ |
|
39 |
send_bytes(s, str, m.u.line_size); |
|
5 | 40 |
} |
41 |
||
22 | 42 |
static struct Job * findjob(int jobid) |
43 |
{ |
|
44 |
struct Job *p; |
|
45 |
||
46 |
/* Show Queued or Running jobs */ |
|
47 |
p = firstjob; |
|
48 |
while(p != 0) |
|
49 |
{ |
|
50 |
if (p->jobid == jobid) |
|
51 |
return p; |
|
52 |
p = p->next; |
|
53 |
} |
|
54 |
||
55 |
return 0; |
|
56 |
} |
|
57 |
||
19
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
58 |
void s_mark_job_running() |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
59 |
{ |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
60 |
firstjob->state = RUNNING; |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
61 |
} |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
62 |
|
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
63 |
static const char * jstate2string(enum Jobstate s) |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
64 |
{ |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
65 |
char * jobstate; |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
66 |
switch(s) |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
67 |
{ |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
68 |
case QUEUED: |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
69 |
jobstate = "queued"; |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
70 |
break; |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
71 |
case RUNNING: |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
72 |
jobstate = "running"; |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
73 |
break; |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
74 |
case FINISHED: |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
75 |
jobstate = "finished"; |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
76 |
break; |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
77 |
} |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
78 |
return jobstate; |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
79 |
} |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
80 |
|
3 | 81 |
void s_list(int s) |
82 |
{ |
|
83 |
int i; |
|
84 |
struct Job *p; |
|
5 | 85 |
char buffer[LINE_LEN]; |
3 | 86 |
|
22 | 87 |
sprintf(buffer, " ID\tState\tOutput\tCommand\n"); |
5 | 88 |
send_list_line(s,buffer); |
3 | 89 |
|
19
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
90 |
/* Show Queued or Running jobs */ |
3 | 91 |
p = firstjob; |
92 |
while(p != 0) |
|
93 |
{ |
|
19
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
94 |
const char * jobstate; |
22 | 95 |
const char * output_filename; |
19
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
96 |
jobstate = jstate2string(p->state); |
22 | 97 |
if (p->output_filename == 0) |
98 |
output_filename = "stdout"; |
|
99 |
else |
|
100 |
output_filename = p->output_filename; |
|
101 |
sprintf(buffer, "%i\t%s\t%s\t%s\n", |
|
5 | 102 |
p->jobid, |
19
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
103 |
jobstate, |
22 | 104 |
output_filename, |
5 | 105 |
p->command); |
106 |
send_list_line(s,buffer); |
|
3 | 107 |
p = p->next; |
108 |
} |
|
19
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
109 |
|
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
110 |
p = first_finished_job; |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
111 |
|
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
112 |
if (p != 0) |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
113 |
{ |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
114 |
sprintf(buffer, "Finsihed jobs:\n"); |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
115 |
send_list_line(s,buffer); |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
116 |
|
22 | 117 |
sprintf(buffer, " ID\tState\tOutput\tE-level\tCommand\n"); |
19
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
118 |
send_list_line(s,buffer); |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
119 |
|
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
120 |
/* Show Finished jobs */ |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
121 |
while(p != 0) |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
122 |
{ |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
123 |
const char * jobstate; |
22 | 124 |
const char * output_filename; |
19
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
125 |
jobstate = jstate2string(p->state); |
22 | 126 |
if (p->output_filename == 0) |
127 |
output_filename = "stdout"; |
|
128 |
else |
|
129 |
output_filename = p->output_filename; |
|
130 |
sprintf(buffer, "%i\t%s\t%s\t%i\t%s\n", |
|
19
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
131 |
p->jobid, |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
132 |
jobstate, |
22 | 133 |
output_filename, |
19
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
134 |
p->errorlevel, |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
135 |
p->command); |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
136 |
send_list_line(s,buffer); |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
137 |
p = p->next; |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
138 |
} |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
139 |
} |
3 | 140 |
} |
141 |
||
142 |
static struct Job * newjobptr() |
|
143 |
{ |
|
144 |
struct Job *p; |
|
145 |
||
146 |
if (firstjob == 0) |
|
147 |
{ |
|
148 |
firstjob = (struct Job *) malloc(sizeof(*firstjob)); |
|
149 |
firstjob->next = 0; |
|
150 |
return firstjob; |
|
151 |
} |
|
152 |
||
153 |
p = firstjob; |
|
154 |
while(p->next != 0) |
|
155 |
p = p->next; |
|
156 |
||
157 |
p->next = (struct Job *) malloc(sizeof(*p)); |
|
158 |
p->next->next = 0; |
|
159 |
||
160 |
return p->next; |
|
161 |
} |
|
162 |
||
163 |
/* Returns job id */ |
|
18 | 164 |
int s_newjob(int s, struct msg *m) |
3 | 165 |
{ |
166 |
struct Job *p; |
|
18 | 167 |
int res; |
3 | 168 |
|
169 |
p = newjobptr(); |
|
170 |
||
171 |
p->jobid = jobids++; |
|
172 |
p->state = QUEUED; |
|
18 | 173 |
|
174 |
/* load the command */ |
|
175 |
p->command = malloc(m->u.newjob.command_size); |
|
176 |
/* !!! Check retval */ |
|
177 |
res = recv_bytes(s, p->command, m->u.newjob.command_size); |
|
178 |
assert(res != -1); |
|
3 | 179 |
|
180 |
return p->jobid; |
|
181 |
} |
|
182 |
||
183 |
void s_removejob(int jobid) |
|
184 |
{ |
|
185 |
struct Job *p; |
|
186 |
struct Job *newnext; |
|
187 |
||
188 |
if (firstjob->jobid == jobid) |
|
189 |
{ |
|
190 |
struct Job *newfirst; |
|
191 |
/* First job is to be removed */ |
|
192 |
newfirst = firstjob->next; |
|
18 | 193 |
free(firstjob->command); |
3 | 194 |
free(firstjob); |
195 |
firstjob = newfirst; |
|
196 |
return; |
|
197 |
} |
|
198 |
||
199 |
p = firstjob; |
|
200 |
/* Not first job */ |
|
201 |
while (p->next != 0) |
|
202 |
{ |
|
203 |
if (p->next->jobid == jobid) |
|
204 |
break; |
|
205 |
p = p->next; |
|
206 |
} |
|
207 |
assert(p->next != 0); |
|
208 |
||
209 |
newnext = p->next->next; |
|
210 |
||
18 | 211 |
free(p->next->command); |
3 | 212 |
free(p->next); |
213 |
p->next = newnext; |
|
214 |
} |
|
8 | 215 |
|
216 |
/* -1 if no one should be run. */ |
|
217 |
int next_run_job() |
|
218 |
{ |
|
219 |
if (state == WAITING) |
|
220 |
return -1; |
|
221 |
||
222 |
if (firstjob != 0) |
|
9 | 223 |
{ |
224 |
state = WAITING; |
|
8 | 225 |
return firstjob->jobid; |
9 | 226 |
} |
8 | 227 |
|
228 |
return -1; |
|
229 |
} |
|
230 |
||
19
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
231 |
/* Add the job to the finished queue. */ |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
232 |
static void new_finished_job(struct Job *j) |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
233 |
{ |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
234 |
struct Job *p; |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
235 |
|
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
236 |
if (first_finished_job == 0) |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
237 |
{ |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
238 |
first_finished_job = j; |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
239 |
first_finished_job->next = 0; |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
240 |
return; |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
241 |
} |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
242 |
|
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
243 |
p = first_finished_job; |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
244 |
while(p->next != 0) |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
245 |
p = p->next; |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
246 |
|
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
247 |
p->next = j; |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
248 |
p->next->next = 0; |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
249 |
|
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
250 |
return; |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
251 |
} |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
252 |
|
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
253 |
void job_finished(int errorlevel) |
8 | 254 |
{ |
255 |
struct Job *newfirst; |
|
256 |
||
257 |
assert(state == WAITING); |
|
258 |
assert(firstjob != 0); |
|
259 |
||
19
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
260 |
assert(firstjob->state == RUNNING); |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
261 |
|
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
262 |
/* Mark state */ |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
263 |
firstjob->state = FINISHED; |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
264 |
firstjob->errorlevel = errorlevel; |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
265 |
|
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
266 |
/* Add it to the finished queue */ |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
267 |
new_finished_job(firstjob); |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
268 |
|
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
269 |
/* Remove it from the run queue */ |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
270 |
firstjob = firstjob->next; |
8 | 271 |
|
272 |
state = FREE; |
|
273 |
} |
|
20
d85b4c0745fa
"-c" added, for clearing the finished tasks' list.
viric@llimona
parents:
19
diff
changeset
|
274 |
|
d85b4c0745fa
"-c" added, for clearing the finished tasks' list.
viric@llimona
parents:
19
diff
changeset
|
275 |
void s_clear_finished() |
d85b4c0745fa
"-c" added, for clearing the finished tasks' list.
viric@llimona
parents:
19
diff
changeset
|
276 |
{ |
d85b4c0745fa
"-c" added, for clearing the finished tasks' list.
viric@llimona
parents:
19
diff
changeset
|
277 |
struct Job *p; |
d85b4c0745fa
"-c" added, for clearing the finished tasks' list.
viric@llimona
parents:
19
diff
changeset
|
278 |
|
22 | 279 |
if (first_finished_job == 0) |
20
d85b4c0745fa
"-c" added, for clearing the finished tasks' list.
viric@llimona
parents:
19
diff
changeset
|
280 |
return; |
22 | 281 |
|
282 |
p = first_finished_job; |
|
283 |
first_finished_job = 0; |
|
20
d85b4c0745fa
"-c" added, for clearing the finished tasks' list.
viric@llimona
parents:
19
diff
changeset
|
284 |
|
d85b4c0745fa
"-c" added, for clearing the finished tasks' list.
viric@llimona
parents:
19
diff
changeset
|
285 |
while (p->next != 0) |
d85b4c0745fa
"-c" added, for clearing the finished tasks' list.
viric@llimona
parents:
19
diff
changeset
|
286 |
{ |
d85b4c0745fa
"-c" added, for clearing the finished tasks' list.
viric@llimona
parents:
19
diff
changeset
|
287 |
struct Job *tmp; |
d85b4c0745fa
"-c" added, for clearing the finished tasks' list.
viric@llimona
parents:
19
diff
changeset
|
288 |
tmp = p->next; |
22 | 289 |
free(p->command); |
290 |
free(p->output_filename); |
|
20
d85b4c0745fa
"-c" added, for clearing the finished tasks' list.
viric@llimona
parents:
19
diff
changeset
|
291 |
free(p); |
d85b4c0745fa
"-c" added, for clearing the finished tasks' list.
viric@llimona
parents:
19
diff
changeset
|
292 |
p = tmp; |
d85b4c0745fa
"-c" added, for clearing the finished tasks' list.
viric@llimona
parents:
19
diff
changeset
|
293 |
} |
d85b4c0745fa
"-c" added, for clearing the finished tasks' list.
viric@llimona
parents:
19
diff
changeset
|
294 |
|
d85b4c0745fa
"-c" added, for clearing the finished tasks' list.
viric@llimona
parents:
19
diff
changeset
|
295 |
free(p->next); |
d85b4c0745fa
"-c" added, for clearing the finished tasks' list.
viric@llimona
parents:
19
diff
changeset
|
296 |
} |
22 | 297 |
|
298 |
void s_process_runjob_ok(int jobid, char *oname) |
|
299 |
{ |
|
300 |
struct Job *p; |
|
301 |
p = findjob(jobid); |
|
302 |
assert(p != 0); |
|
303 |
assert(p->state == RUNNING); |
|
304 |
||
305 |
p->output_filename = oname; |
|
306 |
} |