summaryrefslogtreecommitdiff
path: root/system/std.zusatz/1.7.3/src/spool manager
blob: 8f9ab9fcc7f686bd0b02fa7f27e6a4a76391cead (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
PACKET spool manager DEFINES                         (* Autor: J. Liedtke *)
    spool manager, server channel:                   (* 21.05.84          *)
 
 
LET que size       = 100 ,

    ack            = 0 ,
    nak            = 1 ,
    error nak      = 2 ,
    second phase ack = 5 ,

    fetch code     = 11 ,
    save code      = 12 ,
    erase code     = 14 ,
    list code      = 15 ,
    all code       = 17 ,
    continue code  = 100,

    empty          = 0 ,
    used           = 1 ;

TASK VAR order task , waiting server , from task , server ;
INT VAR order code , reply , first , last , list index ;

DATASPACE VAR ds ;

TEXT VAR from title ;

BOUND STRUCT (TEXT name, write pass, read pass) VAR msg ;
BOUND TEXT VAR error msg ;
BOUND STRUCT (TEXT tname, tpass, TASK task) VAR sv msg ;

FILE VAR list file ;
TEXT VAR entry name, entry task;

INT VAR command index , params ;
TEXT VAR command line, param 1, param 2 ;
 
LET spool command list =
"break:1.0start:2.01stop:4.0first:5.0killer:6.0 " ;


LET ENTRY = STRUCT (TEXT title, TASK origin, DATASPACE space, INT status) ;

ROW que size ENTRY VAR que ;


INT VAR server chan := 0; 
 
PROC server channel (INT CONST ch): 
  server chan := ch 
 
END PROC server channel; 
 
INT PROC server channel: 
  server chan 
 
END PROC server channel; 
 
PROC spool manager (PROC server start) :
  INT VAR old heap size := heap size;
  begin (PROC server start, server) ;
  set autonom ;
  break ;
  disable stop ;
  first := 1 ;
  last  := 1 ;
  from task := niltask ;
  waiting server := niltask ;
  spool ;
  clear error ;
  forget all dataspaces.

forget all dataspaces :
  INT VAR i ;
  FOR i FROM 1 UPTO que size REP
    forget (que (i).space)
  PER .

spool:
  REP
    wait (ds, order code, order task) ;
    IF   order code = fetch code    THEN out of que
    ELIF order code = save code     THEN prepare into que
    ELIF order code = second phase ack THEN into que
    ELIF order code = erase code    THEN delete que entry
    ELIF order code = list code     THEN list spool
    ELIF order code = all code      THEN y all
    ELIF order code >= continue code
       AND order task = supervisor  THEN spool command (PROC server start)
    FI;
    clear error
  PER;
  collect heap garbage if necessary. 
 
collect heap garbage if necessary: 
  IF heap size > old heap size + 2 
  THEN collect heap garbage; 
       old heap size := heap size 
  FI.

ENDPROC spool manager ;

PROC out of que :

  forget (ds) ;
  IF NOT (order task < myself)
    THEN error ("not parent")
  ELIF que empty
    THEN waiting server := order task
    ELSE send (order task, ack, que (first).space) ;
         inc first
  FI .

que empty :   first = last .

ENDPROC out of que ;

PROC inc first :

  que (first).status := empty ;
  REP
    first := first MOD que size + 1 ;
  UNTIL first = last OR que (first).status <> empty PER

ENDPROC inc first ;

PROC dec first :

  first DECR 1 ;
  IF first = 0
    THEN first := que size
  FI

ENDPROC dec first ;

PROC prepare into que :

  msg := ds ;
  from task := order task ;
  from title := CONCR (msg).name ;
  send (order task,  second phase ack, ds) .

ENDPROC prepare into que ;

PROC into que :

  IF order task = from task
    THEN try entry into spool
    ELSE send (order task, nak, ds)
  FI .

try entry into spool :
  IF que full
    THEN error ("spool overflow")
    ELSE entry (que (last)) ;
         last := next (last) ;
         send (order task, ack, ds) ;
         awake server if necessary
  FI .
 
awake server if necessary :
  IF NOT is niltask (waiting server)
    THEN send (waiting server, ack, que (first).space , reply) ;
         IF reply = ack
           THEN waiting server := niltask ;
                inc first
         FI
  FI .

que full  :   first = next (last) .

ENDPROC into que ;

PROC entry (ENTRY VAR que entry) :

  que entry.title   := from title ;
  que entry.origin  := from task ;
  que entry.space   := ds ;
  que entry.status  := used ;

ENDPROC entry ;

INT PROC next (INT CONST index) :

  index MOD que size + 1 

ENDPROC next ;


PROC delete que entry :

  msg := ds ;
  INT VAR index := first ;
  WHILE index <> last REP
    IF entry found
      THEN erase entry (index) ;
           send (order task, ack, ds) ;
           LEAVE delete que entry
    FI ;
    index := next (index)
  PER ;
  error ("your file does not exist") .

entry found :
  entry.status = used CAND entry.origin = order task
  CAND entry.title = CONCR (msg).name .

entry :  que (index) .

ENDPROC delete que entry ;

PROC erase entry (INT CONST index) :

  entry.status := empty ;
  forget (entry.space) ;
  IF index = first
    THEN inc first
  FI .

entry : que (index) .

ENDPROC erase entry ;

PROC list spool :

  forget (ds) ;
  ds := nilspace ;
  list file := sequential file (output, ds) ;
  to first que entry ; 
  get next que entry (entry name, entry task) ; 
  WHILE entry name <> "" REP 
    putline (list file, text (entry task, 15) + " : " + entry name);
    get next que entry (entry name, entry task)
  PER;
  send (order task, ack, ds) .

ENDPROC list spool ;

BOUND THESAURUS VAR all thesaurus;
 
PROC y all:
  forget (ds); 
  ds := nilspace;
  all thesaurus := ds; 
  all thesaurus := empty thesaurus; 
  to first que entry; 
  get next que entry (entry name, entry task);   (* hier erster Eintrag *) 
  WHILE entryname <> "" REP 
    IF entry task = name (order task) 
      AND NOT (all thesaurus CONTAINS entry name)
      THEN insert (all thesaurus, entry name) 
    FI; 
    get next que entry (entry name, entry task) 
  PER;
  send (order task, ack, ds) 
 
END PROC y all; 
 
PROC to first que entry :

  list index := first - 1

ENDPROC to first que entry ;

PROC get next que entry (TEXT VAR entry name, origin task name): 
 
  WHILE list index <> last REP
    list index := next (list index)
  UNTIL que (list index).status <> empty PER ;
  IF que (list index).status = used
    THEN origin task name := name (que (list index).origin) ;
         entry name := que (list index).title
    ELSE entry name := ""; 
         origin task name := ""
  FI .

ENDPROC get next que entry ;

PROC error (TEXT CONST error text) :

  forget (ds) ;
  ds := nilspace ;
  error msg := ds ;
  CONCR (error msg) := error text ;
  send (order task, error nak, ds)

ENDPROC error ;

PROC spool command (PROC server start) :

  enable stop ;
  continue (order code - continue code) ;
  command dialogue (TRUE) ;
  disable stop ;
  REP 
    get command ("gib spoolkommando :", command line);
    analyze command (spool command list, command line, 3,
                     command index, params, param1, param2);
    execute command
  PER .

execute command :
  SELECT command index OF 
    CASE 1 : break cmd 
    CASE 2 : start cmd
    CASE 3 : start channel cmd
    CASE 4 : stop cmd
    CASE 5 : first cmd
    CASE 6 : killer cmd
  OTHERWISE  do (command line) END SELECT .

start channel cmd: 
  server channel (int (param1)); 
  start cmd; 
  break cmd. 
 
break cmd: 
  break; set autonom  ; LEAVE spool command. 

start cmd :
  IF is niltask (server)
    THEN begin (PROC server start, server)
  FI .

stop cmd :
  IF NOT is niltask (server)
    THEN command dialogue (FALSE) ;
         end (server) ;
         server := niltask 
  FI .

first cmd :
  line ;
  to first que entry ;
  get next que entry (entry name, entry task);
  IF entry name = ""
    THEN LEAVE first cmd
  FI ;
  REP
    get next que entry (entry name, entry task) ;
    IF entry name = ""
      THEN LEAVE first cmd
    FI;
    say (text (entry task, 15) + " : " + entry name) ;
    IF yes ("   als erstes")
      THEN make to first entry ;
           LEAVE first cmd
    FI 
  PER .

make to first entry :
  IF first = next (last)
    THEN errorstop ("spool overflow")
    ELSE dec first ;
         que (first) := que (list index) ;
         erase entry (list index)
  FI .


killer cmd :
  line ;
  to first que entry ;
  REP
    get next que entry (entry name, entry task) ;
    IF entry name = "" 
      THEN LEAVE killer cmd
    FI ;
    say (text (entry task, 15) + " : " + entry name) ;
    IF yes ("   loeschen")
      THEN erase entry (list index)
    FI 
  PER .
 
ENDPROC spool command ;

ENDPACKET spool manager ;