1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 mu_quiesce: proc;
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 ^L
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 ^L
132 quiesce_quiet: quiet: entry (db_path, quiesce_wait_time, code);
133 dcl db_path char (168);
134 dcl quiesce_wait_time fixed bin (17);
135 dcl code fixed bin (35) parm;
136
137
138 hold_ul_ptr, dbc_ptr = null ();
139 handling_a_cleanup = "0"b;
140 on cleanup begin;
141 handling_a_cleanup = "1"b;
142 call tidy_up;
143 end;
144 code = 0;
145
146
147 call get_dbc_ptr (bc, dbc_ptr);
148
149
150 call set_lock_$lock (dbc.quiesce_lock,
151 quiesce_wait_time,
152 icode);
153 if icode ^= 0 then do;
154 if icode = error_table_$lock_wait_time_exceeded
155 then call error (mdbm_error_$db_busy);
156 if icode = error_table_$invalid_lock_reset
157 then do;
158 dbc.trouble_switch = "1"b;
159 call error (mdbm_error_$quiesced_dead_db);
160 end;
161 if icode = error_table_$locked_by_this_process
162 then call error (mdbm_error_$my_quiesced_db);
163 call error (icode);
164 end;
165
166 time_remaining = quiesce_wait_time;
167 go to check_opens;
168
169 do while (time_remaining > 0);
170
171
172 time_remaining = time_remaining - 30;
173 call timer_manager_$sleep (30, "11"b);
174
175 check_opens: ;
176
177
178 call set_lock_$lock (dbc.open_lock,
179 quiesce_wait_time,
180 icode);
181 if icode ^= 0 then do;
182 if icode = error_table_$lock_wait_time_exceeded
183 then call error (mdbm_error_$db_busy);
184 if icode = error_table_$invalid_lock_reset
185 then do;
186 dbc.trouble_switch = "1"b;
187 call error (mdbm_error_$trouble_lock);
188 end;
189 else call error (icode);
190 end;
191
192
193 if dbc.trouble_switch then do;
194 call set_lock_$unlock (dbc.open_lock, icode);
195 call error (mdbm_error_$trouble_lock);
196 end;
197
198
199 if dbc.open_users = 0 then go to quiesce_db_ok;
200
201
202 call set_lock_$unlock (dbc.open_lock, icode);
203 if icode ^= 0 then call error (icode);
204 end;
205
206
207 call error (mdbm_error_$db_busy);
208
209 quiesce_db_ok: ;
210 quiesce_sw = "1"b;
211 quiesce_db = "1"b;
212
213
214 num_filns = 0;
215 allocate user_list in (dbc.static_area) set (hold_ul_ptr);
216 ul_ptr = hold_ul_ptr;
217 call get_lock_id_ (user_list.db_lock_id);
218 if icode ^= 0 then call error (icode);
219 user_list.rdbi_bits = "0"b;
220 user_list.num_filns = 0;
221 user_list.fil_list_ofs = NULL_OFS;
222 user_list.next_active_ofs = NULL_OFS;
223 user_list.next_waiting_ofs = NULL_OFS;
224 user_list.next_open_ofs = dbc.open_users_ofs;
225
226 dbc.open_users_ofs = rel (ul_ptr);
227 user_list.group_id = get_group_id_ ();
228 user_list.open_mode = mdbm_data_$quiesce_mode;
229 user_list.bypass_count = 0;
230 user_list.allowance_count = 0;
231 user_list.process_id = get_process_id_ ();
232 user_list.ev_chn_id = 0;
233 user_list.dead_proc = "0"b;
234 user_list.dead_proc_conflict = "0"b;
235 user_list.priority_high = "0"b;
236 user_list.waiting_sw = "0"b;
237 user_list.active_sw = "0"b;
238 user_list.event_signal_sw = "0"b;
239 user_list.passive_sw = "1"b;
240 call set_lock_$unlock (dbc.open_lock, icode);
241 if icode ^= 0 then call error (icode);
242 go to common_exit;
243 ^L
244 quiesce_free: free: entry (db_path, code);
245
246
247 hold_ul_ptr, dbc_ptr = null ();
248 handling_a_cleanup = "0"b;
249 on cleanup begin;
250 handling_a_cleanup = "1"b;
251 call tidy_up;
252 end;
253 code = 0;
254
255
256 call get_dbc_ptr (bc, dbc_ptr);
257
258
259
260
261 call get_lock_id_ (lock_id);
262 if dbc.quiesce_lock ^= lock_id
263 then do;
264 call set_lock_$lock (dbc.quiesce_lock,
265 0, icode);
266 if icode = 0
267 then do;
268 call free_db;
269 call error (mdbm_error_$free_not_quiesced);
270 end;
271 else if icode = error_table_$invalid_lock_reset
272 then do;
273 dbc.trouble_switch = "1"b;
274 call error (mdbm_error_$quiesced_dead_db);
275 end;
276 else if icode = error_table_$lock_wait_time_exceeded
277 then call error (mdbm_error_$quiesced_db);
278 else call error (icode);
279 end;
280 else do;
281 call free_db;
282 end;
283 common_exit: ;
284 return;
285 ^L
286 convert: proc (a_ptr, ofs) returns (ptr);
287
288
289
290
291
292 dcl result ptr;
293 dcl a_ptr ptr;
294 dcl ofs bit (18) unal;
295
296 dcl (null, ptr) builtin;
297
298 if ofs ^= NULL_OFS
299 then result = ptr (a_ptr, ofs);
300 else result = null;
301
302 return (result);
303
304 end convert;
305 ^L
306 delete_quiesce_user_from_list: proc;
307
308
309
310
311
312 previous_ul_ptr = null ();
313 proc_id = get_process_id_ ();
314 do ul_ptr = convert (dbc_ptr, dbc.open_users_ofs)
315 repeat convert (dbc_ptr, user_list.next_open_ofs)
316 while (ul_ptr ^= null ());
317 if user_list.process_id = proc_id
318 & user_list.open_mode = mdbm_data_$quiesce_mode
319 then do;
320 hold_ul_ptr = ul_ptr;
321 if previous_ul_ptr = null ()
322 then dbc.open_users_ofs = user_list.next_open_ofs;
323 else previous_ul_ptr -> user_list.next_open_ofs = user_list.next_open_ofs;
324 go to free_user_storage;
325 dcl proc_id bit (36);
326 dcl previous_ul_ptr ptr;
327 end;
328 previous_ul_ptr = ul_ptr;
329 end;
330 free_user_storage: ;
331 if hold_ul_ptr ^= null ()
332 then free hold_ul_ptr -> user_list in (dbc.static_area);
333 return;
334 end delete_quiesce_user_from_list;
335 ^L
336 error: proc (cd);
337 dcl cd fixed bin (35) parm;
338 code = cd;
339 call tidy_up;
340 go to common_exit;
341 end error;
342 ^K^K
343 free_db: proc;
344 call set_lock_$lock (dbc.open_lock,
345 mdbm_data_$lock_wait, icode);
346 if icode ^= 0 then do;
347 if icode = error_table_$lock_wait_time_exceeded
348 then call error (mdbm_error_$db_busy);
349 if icode = error_table_$invalid_lock_reset
350 then do;
351 dbc.trouble_switch = "1"b;
352 call error (mdbm_error_$trouble_lock);
353 end;
354 else call error (icode);
355 end;
356
357
358 if dbc.trouble_switch then do;
359 call set_lock_$unlock (dbc.open_lock, icode);
360 call error (mdbm_error_$trouble_lock);
361 end;
362 quiesce_sw = "0"b;
363 quiesce_db = "0"b;
364 call delete_quiesce_user_from_list;
365 call set_lock_$unlock (dbc.open_lock, icode);
366 if icode ^= 0 then call error (icode);
367 call set_lock_$unlock (dbc.quiesce_lock, icode);
368 if icode ^= 0 then call error (icode);
369 return;
370 end free_db;
371 ^L
372 get_dbc_ptr: proc (bc, dbc_ptr);
373 dcl bc fixed bin (24) parm;
374 dcl dbc_ptr ptr parm;
375
376
377
378
379 call mu_concurrency_control$open_control_segment (db_path,
380 dbc_ptr, bc, icode);
381 if icode ^= 0 then
382 call error (icode);
383
384 return;
385 end get_dbc_ptr;
386 ^L
387 tidy_up: proc;
388
389
390
391 if code = mdbm_error_$my_quiesced_db then return;
392 if code = mdbm_error_$hold_quiesced_db then return;
393 if code = mdbm_error_$quiesce_too_few then return;
394 if dbc_ptr = null () then return;
395 call get_lock_id_ (lock_id);
396 if dbc.quiesce_lock ^= lock_id
397 then return;
398 if handling_a_cleanup
399 then call set_lock_$lock (dbc.open_lock,
400 mdbm_data_$cleanup_lock_wait, icode);
401 else call set_lock_$lock (dbc.open_lock,
402 mdbm_data_$lock_wait, icode);
403 if icode = 0 | icode = error_table_$locked_by_this_process
404 then do;
405 quiesce_sw = "0"b;
406 quiesce_db = "0"b;
407 call delete_quiesce_user_from_list;
408 call set_lock_$unlock (dbc.open_lock, icode);
409 call set_lock_$unlock (dbc.quiesce_lock, icode);
410 end;
411 end tidy_up;
412 ^L
413
414 dcl bc fixed bin (24);
415 dcl cleanup condition;
416 dcl error_table_$invalid_lock_reset ext fixed bin (35);
417 dcl error_table_$lock_wait_time_exceeded ext fixed bin (35);
418 dcl error_table_$locked_by_this_process ext fixed bin (35);
419 dcl get_group_id_ entry returns (char (32));
420 dcl get_lock_id_ entry (bit (36) aligned);
421 dcl get_process_id_ entry returns (bit (36));
422 dcl handling_a_cleanup bit (1) aligned;
423 dcl hold_ul_ptr ptr;
424
425 dcl icode fixed bin (35);
426 dcl lock_id bit (36) aligned;
427 dcl mdbm_data_$cleanup_lock_wait ext fixed bin (17);
428 dcl mdbm_data_$lock_wait ext fixed bin (17);
429 dcl mdbm_data_$quiesce_mode ext fixed bin (17);
430 dcl mdbm_error_$db_busy ext fixed bin (35);
431 dcl mdbm_error_$free_not_quiesced ext fixed bin (35);
432 dcl mdbm_error_$hold_quiesced_db ext fixed bin (35);
433 dcl mdbm_error_$my_quiesced_db ext fixed bin (35);
434 dcl mdbm_error_$quiesce_too_few ext fixed bin (35);
435 dcl mdbm_error_$quiesced_db ext fixed bin (35);
436 dcl mdbm_error_$quiesced_dead_db ext fixed bin (35);
437 dcl mdbm_error_$trouble_lock ext fixed bin (35);
438 dcl set_lock_$lock entry (bit (36) aligned, fixed bin, fixed bin (35));
439 dcl set_lock_$unlock entry (bit (36) aligned, fixed bin (35));
440 dcl sys_info$max_seg_size ext fixed bin (35);
441 dcl time_remaining fixed bin (71);
442 dcl timer_manager_$sleep entry (fixed bin (71), bit (2));
443 dcl mu_concurrency_control$open_control_segment entry (char (168), ptr, fixed bin (24), fixed bin (35));
444 dcl (fixed, null, rel) builtin;
445 ^L
446 %include mdbm_dbc;
447 ^L
448 %include mdbm_users;
449 end mu_quiesce;