1 
  2 
  3 
  4 
  5 
  6 
  7 
  8 
  9 
 10 
 11 
 12 
 13 hc_ipc:
 14      procedure;
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
 29 
 30 
 31 
 32 
 33 
 34 
 35 dcl       ipc_validate_$decode_event_channel_name
 36                               entry (fixed bin (18), fixed bin (35), fixed bin (71), bit (3) aligned, fixed bin (15),
 37                               fixed bin (3), bit (1) aligned, fixed bin (18), fixed bin (35));
 38 dcl       ipc_validate_$encode_event_channel_name
 39                               entry (fixed bin (18), fixed bin (35), bit (3) aligned, fixed bin (15), fixed bin (3),
 40                               bit (1) aligned, fixed bin (18), fixed bin (71));
 41 dcl       level$get           entry returns (fixed bin (3));
 42 dcl       access_audit_$log_general
 43                               entry options (variable);
 44 dcl       pxss$free_itt       entry (bit (18) aligned);
 45 dcl       pxss$wakeup         entry (bit (36) aligned, bit (72) aligned, fixed bin (71), fixed bin (35));
 46 dcl       syserr              entry options (variable);
 47 dcl       tc_util$get_ipc_operands
 48                               entry (fixed bin (18), fixed bin (35));
 49 dcl       tc_util$get_ipc_operands_priv
 50                               entry (bit (36) aligned, fixed bin (18), fixed bin (35), fixed bin (35));
 51 dcl       terminate_proc      entry (fixed bin (35));
 52 
 53 
 54 dcl       last_sender         bit (36) internal static init ("0"b);
 55                                                             
 56 
 57 
 58 
 59 dcl       ME                  char (32) initial ("hc_ipc") internal static options (constant);
 60 dcl       OFF                 bit (1) aligned internal static options (constant) init ("0"b);
 61 dcl       (ON, YES)           bit (1) aligned internal static options (constant) init ("1"b);
 62 dcl       QUITSTOP            char (8) internal static options (constant) init ("quitstop");
 63 
 64 
 65 dcl       access_operations_$ipc_wakeup
 66                               bit (36) aligned ext;
 67 dcl       error_table_$ect_full
 68                               fixed bin (35) ext;
 69 dcl       error_table_$inconsistent_ect
 70                               fixed bin (35) ext;
 71 dcl       error_table_$invalid_channel
 72                               fixed bin (35) ext;
 73 dcl       error_table_$itt_overflow
 74                               fixed bin (35) ext;
 75 dcl       error_table_$process_stopped
 76                               fixed bin (35) ext;
 77 dcl       error_table_$process_unknown
 78                               fixed bin (35) ext;
 79 dcl       error_table_$special_channels_full
 80                               fixed bin (35) ext;
 81 dcl       error_table_$wakeup_denied
 82                               fixed bin (35) ext;
 83 dcl       error_table_$wrong_channel_ring
 84                               fixed bin (35) ext;
 85 
 86 dcl       pds$event_masks     (7) bit (36) aligned ext;
 87 dcl       pds$events_pending  bit (36) aligned ext;
 88 dcl       pds$itt_head        bit (18) aligned ext;
 89 dcl       pds$process_group_id
 90                               char (32) aligned ext;
 91 dcl       pds$process_id      bit (36) aligned ext;
 92 dcl       pds$ring_events     bit (36) aligned ext;         
 93 
 94 dcl       pds$special_channels
 95                               bit (36) aligned ext;
 96 dcl       pds$stacks          (0:7) ext ptr;
 97 dcl       tc_data$            fixed bin (17) ext;
 98 dcl       tc_data$max_channels
 99                               fixed bin (35) ext;
100 
101 
102 
103 
104 dcl       addr                builtin;
105 dcl       index               builtin;
106 dcl       null                builtin;
107 dcl       ptr                 builtin;
108 dcl       string              builtin;
109 dcl       substr              builtin;
110 dcl       unspec              builtin;
111 
112 
113 
114 dcl       area                condition;
115 
116 
117 
118 dcl       channel_ring        fixed bin (3);
119 dcl       code                fixed bin (35);
120 dcl       ev_chn_flags        bit (3) aligned;
121 dcl       ev_chn_index        fixed bin (15);
122 dcl       ev_chn_ring         fixed bin (3);
123 dcl       ev_chn_type         bit (1) aligned;
124 dcl       ev_chn_unique_id    fixed bin (18);
125 dcl       event_channel_name_fb71
126                               fixed bin (71) automatic;
127 dcl       event_channel_message
128                               fixed bin (71);
129 dcl       fast_channel_id     fixed bin (18);
130 dcl       1 event_flags       aligned like audit_event_flags;
131                                                             
132 dcl       1 itt_dummy         like itt_entry aligned;       
133 dcl       itt_relp            bit (18) aligned;
134 dcl       msg_ptr             ptr;                          
135 dcl       r_offset            fixed bin (18);               
136 dcl       r_factor            fixed bin (35);               
137 dcl       target_process      bit (36) aligned;
138 dcl       same_process        bit (1) aligned;
139 dcl       pxss_status         fixed bin (35);
140 dcl       target_ring         fixed bin (3);                
141 dcl       val_ring            fixed bin (3);
142 
143 
144 
145 dcl       ect_area            area (ect_header.ect_area_size) based (ect_header.ect_areap);
146 %page;
147 ipc_wakeup:
148      entry (a_target_process, a_event_channel, a_event_channel_message, a_code);
149 
150 
151 Note
152 
153 
154 
155 
156 dcl       a_target_process    bit (36) aligned parameter;
157 dcl       a_event_channel     fixed bin (71) parameter;
158 dcl       a_event_channel_message
159                               fixed bin (71) parameter;
160 dcl       a_code              fixed bin (35) parameter;
161 
162 
163 
164 
165 
166 
167 
168 
169 
170 
171 
172 
173 
174 
175 
176 
177 
178 
179 
180           code = 0;                                         
181           target_process = a_target_process;                
182           event_channel_name_fb71 = a_event_channel;        
183           event_channel_message = a_event_channel_message;
184 
185           val_ring = level$get ();                          
186 
187           call tc_util$get_ipc_operands_priv (target_process, r_offset, r_factor, code);
188           if code ^= 0
189           then do;
190                     call syserr (LOG, "^a: Denied wakeup by ^a in ring ^d.  Invalid process id ^w.", ME,
191                          pds$process_group_id, val_ring, target_process);
192                     goto WAKEUP_RETURNS;
193                end;
194 
195           call ipc_validate_$decode_event_channel_name (r_offset, r_factor, event_channel_name_fb71, ev_chn_flags,
196                ev_chn_index, ev_chn_ring, ev_chn_type, ev_chn_unique_id, code);
197           if code ^= 0
198           then do;
199                     call syserr (LOG, "^a: Denied wakeup by ^a in ring ^d to process ^w.  Invalid event channel ^24.3b",
200                          ME, pds$process_group_id, val_ring, target_process, unspec (event_channel_name_fb71));
201                     goto WAKEUP_RETURNS;
202                end;
203 
204 
205           same_process = (target_process = pds$process_id);
206 
207 
208 
209 
210           if ev_chn_type = FAST_CHANNEL_TYPE                
211           then do;
212                     if ev_chn_ring < val_ring
213                     then do;
214                               code = error_table_$invalid_channel;
215                               call syserr (LOG,
216                                    "^a: Denied wakeup by ^a in ring ^d to process ^w.  Fast channel (^24.3b) not allowed.",
217                                    ME, pds$process_group_id, val_ring, target_process, unspec (event_channel_name_fb71));
218 
219                               go to WAKEUP_RETURNS;
220                          end;
221                end;
222 
223 
224 
225 
226           else if (same_process = YES)
227           then do;
228                     if ev_chn_ring = val_ring
229                     then do;
230                               unspec (itt_dummy) = "0"b;    
231                                                             
232                               itt_dummy.sender, itt_dummy.target_id = target_process;
233                               itt_dummy.ring = val_ring;
234                               unspec (itt_dummy.channel_id) = unspec (event_channel_name_fb71);
235                               itt_dummy.message = event_channel_message;
236 
237                               on area call ect_error_handler (error_table_$ect_full, target_ring);
238 
239                               call dispatch_message (addr (itt_dummy), target_ring);
240                               if target_ring > 0
241                               then go to WAKEUP_RETURNS;    
242                          end;
243 
244                end;
245 
246 
247 
248 
249           code = 0;                                         
250 
251           call pxss$wakeup (target_process, unspec (event_channel_name_fb71), event_channel_message, pxss_status);
252 
253           if pxss_status = 0
254           then code = error_table_$process_unknown;         
255 
256           else if pxss_status = 5
257           then code = error_table_$process_stopped;         
258 
259           else if pxss_status = 100
260           then do;
261                     string (event_flags) = ""b;
262                     call access_audit_$log_general (ME, val_ring, string (event_flags), access_operations_$ipc_wakeup, "",
263                          0, null (), 0, "Target process (^w) authorization is lower", target_process);
264                     code = error_table_$wakeup_denied;
265                end;
266 
267           else if pxss_status = 200
268           then do;                                          
269                     code = error_table_$itt_overflow;
270                     if pds$process_id ^= last_sender
271                     then do;                                
272                               last_sender = pds$process_id;
273                               call syserr (0, "^a: ITT overflow caused by ^a", ME, pds$process_group_id);
274                          end;
275                end;
276 
277 WAKEUP_RETURNS:
278           a_code = code;
279           return;
280 ^L
281 
282 
283 full_block:
284      entry;
285 
286           val_ring = level$get ();                          
287           on area call ect_error_handler (error_table_$ect_full, target_ring);
288 
289           itte_ptr = addr (tc_data$);
290           do itt_relp = pds$itt_head repeat (itte_ptr -> itt_entry.next_itt_relp) while (itt_relp);
291                                                             
292                itte_ptr = ptr (itte_ptr, itt_relp);
293                call dispatch_message (itte_ptr, target_ring);
294 
295           end;
296 
297           call pxss$free_itt (pds$itt_head);                
298 
299           return;
300 ^L
301 assign_channel:
302      entry (a_channel_name, a_code);
303 
304 dcl       a_channel_name      fixed bin (71);               
305 
306           code = 0;
307 
308           fast_channel_id = index (pds$special_channels, "0"b);
309                                                             
310           if (fast_channel_id > tc_data$max_channels) | (fast_channel_id = 0)
311           then do;                                          
312                     code = error_table_$special_channels_full;
313                     a_channel_name = 0;
314                     go to FAST_CHANNEL_RETURNS;
315                end;
316           substr (pds$special_channels, fast_channel_id, 1) = ON;
317                                                             
318           val_ring = level$get ();
319           substr (pds$event_masks (val_ring), fast_channel_id, 1) = ON;
320                                                             
321           substr (pds$events_pending, fast_channel_id, 1) = OFF;
322                                                             
323 
324 
325 
326 
327           call tc_util$get_ipc_operands (r_offset, r_factor);
328 
329 
330 
331           call ipc_validate_$encode_event_channel_name (r_offset, r_factor, NORMAL_CHANNEL_FLAGS, (fast_channel_id),
332                val_ring, FAST_CHANNEL_TYPE, fast_channel_id, event_channel_name_fb71);
333 
334           unspec (a_channel_name) = unspec (event_channel_name_fb71);
335           go to FAST_CHANNEL_RETURNS;
336 ^L
337 delete_channel:
338      entry (a_channel_name, a_code);
339 
340           unspec (event_channel_name_fb71) = unspec (a_channel_name);
341           code = 0;
342           val_ring = level$get ();
343 
344 
345 
346 
347           call tc_util$get_ipc_operands (r_offset, r_factor);
348 
349           call ipc_validate_$decode_event_channel_name (r_offset, r_factor, event_channel_name_fb71, ev_chn_flags,
350                ev_chn_index, channel_ring, ev_chn_type, fast_channel_id, code);
351           if code ^= 0
352           then goto FAST_CHANNEL_RETURNS;
353 
354           if fast_channel_id ^= ev_chn_index
355           then do;
356                     code = error_table_$invalid_channel;
357                     goto FAST_CHANNEL_RETURNS;
358                end;
359 
360           if val_ring > channel_ring
361           then do;                                          
362                     code = error_table_$wrong_channel_ring;
363                     go to FAST_CHANNEL_RETURNS;
364                end;
365 
366           if ev_chn_type ^= FAST_CHANNEL_TYPE
367           then do;
368                     code = error_table_$invalid_channel;
369                     goto FAST_CHANNEL_RETURNS;
370                end;
371 
372           if fast_channel_id > tc_data$max_channels | fast_channel_id <= 0
373           then do;
374                     code = error_table_$invalid_channel;
375                     go to FAST_CHANNEL_RETURNS;
376                end;
377 
378           if (substr (pds$event_masks (channel_ring), fast_channel_id, 1) = OFF)
379           then do;
380                     code = error_table_$invalid_channel;
381                     go to FAST_CHANNEL_RETURNS;
382                end;
383 
384 
385           substr (pds$event_masks (channel_ring), fast_channel_id, 1) = OFF;
386           substr (pds$special_channels, fast_channel_id, 1) = OFF;
387                                                             
388 FAST_CHANNEL_RETURNS:
389           a_code = code;
390           return;
391 ^L
392 dispatch_message:
393      proc (a_itte_ptr, a_target_ring);
394 
395 dcl       a_itte_ptr          ptr parameter;
396 dcl       a_target_ring       fixed bin (3) parameter;
397 
398 
399 
400 
401           a_target_ring = 0;
402 
403 
404           if unspec (a_itte_ptr -> itt_entry.channel_id) = unspec (QUITSTOP)
405           then return;
406 
407 
408           a_target_ring = addr (a_itte_ptr -> itt_entry.channel_id) -> event_channel_name.ring;
409           if a_target_ring = 0
410           then return;
411           sb = pds$stacks (a_target_ring);
412           if sb = null                                      
413           then return;
414 
415 
416           ect_ptr = sb -> stack_header.ect_ptr;
417 
418 
419 
420 Note
421 
422 
423 
424 
425           if ect_ptr = null
426           then return;
427 
428           if ect_header.ect_areap = null
429           then call ect_error_handler (error_table_$inconsistent_ect, a_target_ring);
430 
431           allocate itt_message in (ect_area) set (msg_ptr);
432           ect_header.count (ITT_MESSAGE) = ect_header.count (ITT_MESSAGE) + 1;
433           ect_header.count (TOTAL) = ect_header.count (TOTAL) + 1;
434           unspec (msg_ptr -> itt_message) = "0"b;
435           msg_ptr -> itt_message.type = ITT_MESSAGE;
436           call thread_itt_message (ect_ptr, msg_ptr);
437 
438           msg_ptr -> itt_message.message_data = a_itte_ptr -> itt_entry, by name;
439 
440           substr (pds$ring_events, a_target_ring, 1) = ON;  
441                                                             
442 
443      end dispatch_message;
444 ^L
445 thread_itt_message:
446      proc (a_ect_ptr, a_msgp);
447 
448 dcl       a_ect_ptr           ptr parameter;
449 dcl       a_msgp              ptr parameter;
450 
451 dcl       prev_ittp           ptr;
452 
453           prev_ittp = a_ect_ptr -> ect_header.lastp (ITT_MESSAGE);
454           if prev_ittp = null
455           then a_ect_ptr -> ect_header.firstp (ITT_MESSAGE) = a_msgp;
456           else prev_ittp -> itt_message.next_itt_msgp = a_msgp;
457           a_ect_ptr -> ect_header.lastp (ITT_MESSAGE) = a_msgp;
458           a_msgp -> itt_message.next_itt_msgp = null;
459 
460      end thread_itt_message;
461 ^L
462 ect_error_handler:
463      proc (a_code, a_ring);
464 
465 dcl       a_code              fixed bin (35) parameter;
466 dcl       a_ring              fixed bin (3) parameter;
467 
468           call syserr (4, "^a: Unable to allocate in ring ^d ECT for ^a", ME, a_ring, pds$process_group_id);
469           call terminate_proc (a_code);
470 
471      end ect_error_handler;
472 
473 
474 %page; %include access_audit_eventflags;
475 %page; %include ect_structures;
476 %page; %include event_channel_name;
477 %page; %include itt_entry;
478 %page; %include stack_header;
479 %page; %include syserr_constants;
480 %page;
481 
482 
483 
484 
485 
486 
487 
488 
489 
490 
491 
492 
493 
494 
495 
496 
497 
498 
499 
500 
501 
502 
503 
504 
505 
506 
507 
508 
509 
510 
511 
512 
513 
514 
515 
516 
517 
518 
519 
520 
521 
522 
523 
524 
525 
526 
527      end hc_ipc;