Start development on 386BSD 0.0
[unix-history] / .ref-BSD-4_3_Net_2 / usr / src / contrib / isode / rosy / rywait.c
CommitLineData
9e8e5516
C
1/* rywait.c - ROSY: wait */
2
3#ifndef lint
4static char *rcsid = "$Header: /f/osi/rosy/RCS/rywait.c,v 7.4 91/02/22 09:42:07 mrose Interim $";
5#endif
6
7/*
8 * $Header: /f/osi/rosy/RCS/rywait.c,v 7.4 91/02/22 09:42:07 mrose Interim $
9 *
10 *
11 * $Log: rywait.c,v $
12 * Revision 7.4 91/02/22 09:42:07 mrose
13 * Interim 6.8
14 *
15 * Revision 7.3 90/12/23 18:42:50 mrose
16 * update
17 *
18 * Revision 7.2 90/07/09 14:48:09 mrose
19 * sync
20 *
21 * Revision 7.1 90/07/01 21:06:41 mrose
22 * pepsy
23 *
24 * Revision 7.0 89/11/23 22:22:05 mrose
25 * Release 6.0
26 *
27 */
28
29/*
30 * NOTICE
31 *
32 * Acquisition, use, and distribution of this module and related
33 * materials are subject to the restrictions of a license agreement.
34 * Consult the Preface in the User's Manual for the full terms of
35 * this agreement.
36 *
37 */
38
39
40/* LINTLIBRARY */
41
42#include <stdio.h>
43#include "rosy.h"
44
45
46#define missingP(p) \
47{ \
48 if (p == NULL) \
49 return rosaplose (roi, ROS_PARAMETER, NULLCP, \
50 "mandatory parameter \"%s\" missing", "p"); \
51}
52
53/* \f WAIT */
54
55int RyWait (sd, id, out, secs, roi)
56int sd,
57 *id,
58 secs;
59caddr_t *out;
60struct RoSAPindication *roi;
61{
62 int reason,
63 result;
64 register struct opsblk *opb;
65
66#ifdef notdef
67 missingP (out);
68#endif
69 missingP (roi);
70
71 if (id) {
72 if ((opb = findopblk (sd, *id, OPB_INITIATOR)) == NULLOPB)
73 return rosaplose (roi, ROS_PARAMETER, NULLCP,
74 "invocation %d not in progress on association %d",
75 *id, sd);
76 }
77 else
78 opb = firstopblk (sd);
79
80 if (out && opb && (opb -> opb_flags & OPB_EVENT)) {
81 *out = opb -> opb_out;
82 *roi = opb -> opb_event; /* struct copy */
83 opb -> opb_out = NULL;
84 freeopblk (opb);
85
86 return OK;
87 }
88
89 if (!id)
90 opb = NULLOPB;
91
92 switch (result = RoWaitRequest (sd, secs, roi)) {
93 case NOTOK:
94 reason = roi -> roi_preject.rop_reason;
95 if (ROS_FATAL (reason))
96 loseopblk (sd, reason);
97 break;
98
99 case DONE:
100 loseopblk (sd, ROS_IP_RELEASE);
101 break;
102
103 case OK:
104 result = RyWaitAux (sd, opb, out, secs, roi);
105 break;
106
107 default:
108 result = rosaplose (roi, ROS_PROTOCOL, NULLCP,
109 "unknown return from RoWaitRequest=%d", result);
110 break;
111 }
112
113 return result;
114}
115
116/* \f */
117
118int RyWaitAux (sd, opb, out, secs, roi)
119int sd;
120register struct opsblk *opb;
121int secs;
122caddr_t *out;
123struct RoSAPindication *roi;
124{
125 int id,
126 reason,
127 result;
128 char *cp;
129 caddr_t in;
130 register struct dspblk *dsb;
131 register struct opsblk *op2;
132 register struct RyError **rye;
133 register struct RyOperation *ryo;
134
135 missingP (roi);
136
137 if (out)
138 *out = NULL;
139
140 for (;;) {
141 switch (roi -> roi_type) {
142 case ROI_INVOKE: {
143 struct RoSAPinvoke roxs;
144 register struct RoSAPinvoke *rox = &roxs;
145
146 *rox = roi -> roi_invoke; /* struct copy */
147
148 if (op2 = findopblk (sd, rox -> rox_id, OPB_RESPONDER)) {
149 (void) rosaplose (roi, result = ROS_IP_DUP, NULLCP,
150 "duplicate invocation %d", rox -> rox_id);
151
152bad_request: ;
153 (void) RoURejectRequest (sd, &rox -> rox_id, result,
154 ROS_NOPRIO, roi);
155 ROXFREE (rox);
156
157 if (opb == NULLOPB)
158 return NOTOK;
159 goto next;
160 }
161
162 if ((dsb = finddsblk (sd, rox -> rox_op)) == NULLDSB
163 && (dsb = finddsblk (NOTOK, rox -> rox_op))
164 == NULLDSB) {
165 (void) rosaplose (roi, result = ROS_IP_UNRECOG, NULLCP,
166 "unexpected invocation %d of operation %d",
167 rox -> rox_id, rox -> rox_op);
168 goto bad_request;
169 }
170
171 ryo = dsb -> dsb_ryo;
172 in = NULL;
173 if (rox -> rox_args) {
174#ifdef PEPSY_DEFINITIONS
175 if (!ryo -> ryo_arg_mod) { /* XXX: MISTYPED? */
176#else
177 if (!ryo -> ryo_arg_decode) { /* XXX: MISTYPED? */
178#endif
179 (void) rosaplose (roi, result = ROS_IP_MISTYPED,
180 NULLCP,
181 "unexpected argument for invocation %d of operation %s/%d",
182 rox -> rox_id, ryo -> ryo_name, ryo -> ryo_op);
183 goto bad_request;
184 }
185
186 PY_pepy[0] = 0;
187#ifdef PEPSY_DEFINITIONS
188 if (dec_f (ryo -> ryo_arg_index, ryo -> ryo_arg_mod,
189 rox -> rox_args, 1, NULLIP, NULLVP, &in)
190 == NOTOK) {
191#else
192 if ((*ryo -> ryo_arg_decode) (rox -> rox_args, 1, NULLIP,
193 NULLVP, &in) == NOTOK) {
194#endif
195 (void) rosaplose (roi, result = ROS_IP_MISTYPED,
196 NULLCP,
197 "mistyped argument for invocation %d of operation %s/%d [%s]",
198 rox -> rox_id, ryo -> ryo_name, ryo -> ryo_op,
199 PY_pepy);
200 goto bad_request;
201 }
202 }
203
204 if (ryo -> ryo_result || ryo -> ryo_errors) {
205 if ((op2 = newopblk (sd, rox -> rox_id)) == NULLOPB) {
206 (void) rosaplose (roi, result = ROS_IP_LIMIT, NULLCP,
207 "unable to allocate opblock for invocation %d of operation %s/%d",
208 rox -> rox_id, ryo -> ryo_name, ryo -> ryo_op);
209 goto bad_request;
210 }
211 op2 -> opb_flags &= ~OPB_INITIATOR;
212 op2 -> opb_flags |= OPB_RESPONDER;
213 op2 -> opb_ryo = ryo;
214 }
215
216 result = (*dsb -> dsb_vector) (sd, ryo, rox, in, roi);
217#ifdef PEPSY_DEFINITIONS
218 if (in && ryo -> ryo_arg_mod)
219 (void) fre_obj (in,
220 ryo -> ryo_arg_mod
221 -> md_dtab[ryo -> ryo_arg_index],
222 ryo -> ryo_arg_mod, 1);
223#else
224 if (in && ryo -> ryo_arg_free)
225 (void) (*ryo -> ryo_arg_free) (in);
226#endif
227 ROXFREE (rox);
228
229 switch (result) {
230 default:
231 result = rosaplose (roi, ROS_PROTOCOL, NULLCP,
232 "%s invoke dispatch for invoke id %d returns %d",
233 ryo -> ryo_name, rox -> rox_id, result);
234 /* and fall */
235 case NOTOK:
236 if (opb != NULLOPB)
237 break;
238 case DONE:
239 return result;
240
241 case OK:
242 break;
243 }
244 goto next;
245 }
246
247 case ROI_RESULT: {
248 register struct RoSAPresult *ror = &roi -> roi_result;
249
250 if ((op2 = findopblk (sd, ror -> ror_id, OPB_INITIATOR))
251 == NULLOPB
252 || (op2 -> opb_flags & OPB_EVENT)) {
253 (void) RoURejectRequest (sd, &ror -> ror_id,
254 ROS_RRP_UNRECOG, ROS_NOPRIO, roi);
255 RORFREE (ror);
256 goto next;
257 }
258
259 ryo = op2 -> opb_ryo;
260 if (!ryo -> ryo_result) {
261 result = ROS_RRP_UNEXP;
262
263bad_result: ;
264 RORFREE (ror);
265 goto bad_response;
266 }
267
268#ifdef PEPSY_DEFINITIONS
269 if (ryo -> ryo_res_mod) { /* XXX: MISTYPED? */
270#else
271 if (ryo -> ryo_res_decode) { /* XXX: MISTYPED? */
272#endif
273 if (!ror -> ror_result) {
274 result = ROS_RRP_MISTYPED;
275 goto bad_result;
276 }
277 PY_pepy[0] = 0;
278#ifdef PEPSY_DEFINITIONS
279 result = dec_f (ryo -> ryo_res_index,
280 ryo -> ryo_res_mod, ror -> ror_result,
281 1, NULLIP, NULLVP, &op2 -> opb_out);
282 op2 -> opb_free_index = ryo -> ryo_res_index;
283 op2 -> opb_free_mod = ryo -> ryo_res_mod;
284#else
285 result = (*ryo -> ryo_res_decode) (ror -> ror_result, 1,
286 NULLIP, NULLVP, &op2 -> opb_out);
287 op2 -> opb_free = ryo -> ryo_res_free;
288#endif
289 }
290 else {
291 if (ror -> ror_result) {
292 result = ROS_RRP_MISTYPED;
293 goto bad_result;
294 }
295
296 result = OK;
297 }
298
299 op2 -> opb_pe = ror -> ror_result, ror -> ror_result = NULLPE;
300 RORFREE (ror);
301
302 if (result == NOTOK) {
303 result = ROS_RRP_MISTYPED;
304 goto bad_response;
305 }
306
307 if (op2 -> opb_resfnx) {
308 result = (*op2 -> opb_resfnx) (sd, op2 -> opb_id,
309 RY_RESULT, op2 -> opb_out,
310 roi);
311 freeopblk (op2);
312
313 id = ror -> ror_id, cp = "result";
314punch: ;
315 switch (result) {
316 default:
317 result = rosaplose (roi, ROS_PROTOCOL, NULLCP,
318 "%s %s dispatch for invoke id %d returns %d",
319 ryo -> ryo_name, cp, id, result);
320 /* and fall */
321 case NOTOK:
322 if (opb != NULLOPB)
323 break;
324 case DONE:
325 return result;
326
327 case OK:
328 break;
329 }
330 if (opb == op2)
331 return OK;
332 goto next;
333 }
334
335 if (opb == NULLOPB || opb == op2) {
336 if (out == NULL) {
337waiting: ;
338 op2 -> opb_flags |= OPB_EVENT;
339 op2 -> opb_event = *roi; /* struct copy */
340 return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP);
341 }
342
343 *out = op2 -> opb_out;
344 op2 -> opb_out = NULL;
345 freeopblk (op2);
346
347 return OK;
348 }
349
350 op2 -> opb_flags |= OPB_EVENT;
351 op2 -> opb_event = *roi; /* struct copy */
352 goto next;
353 }
354
355 case ROI_ERROR: {
356 register struct RoSAPerror *roe = &roi -> roi_error;
357
358 if ((op2 = findopblk (sd, roe -> roe_id, OPB_INITIATOR))
359 == NULLOPB
360 || (op2 -> opb_flags & OPB_EVENT)) {
361 (void) RoURejectRequest (sd, &roe -> roe_id,
362 ROS_REP_UNRECOG, ROS_NOPRIO, roi);
363 ROEFREE (roe);
364 goto next;
365 }
366
367 ryo = op2 -> opb_ryo;
368 if (!(rye = ryo -> ryo_errors)) {
369 result = ROS_REP_UNEXP;
370
371bad_error: ;
372 ROEFREE (roe);
373 goto bad_response;
374 }
375 for (; *rye; rye++)
376 if ((*rye) -> rye_err == roe -> roe_error)
377 break;
378 if (!*rye) {
379 result = ROS_REP_UNEXPERR;
380 goto bad_error;
381 }
382
383#ifdef PEPSY_DEFINITIONS
384 if ((*rye) -> rye_param_mod) { /* XXX: MISTYPED? */
385#else
386 if ((*rye) -> rye_param_decode) { /* XXX: MISTYPED? */
387#endif
388 if (!roe -> roe_param) {
389 result = ROS_REP_MISTYPED;
390 goto bad_error;
391 }
392
393#ifdef PEPSY_DEFINITIONS
394 result = dec_f( (*rye) -> rye_param_index,
395 (*rye) -> rye_param_mod, roe -> roe_param,
396#else
397 result = (*(*rye) -> rye_param_decode) (roe -> roe_param,
398#endif
399 1, NULLIP, NULLVP, &op2 -> opb_out);
400#ifdef PEPSY_DEFINITIONS
401 op2 -> opb_free_index = (*rye) -> rye_param_index;
402 op2 -> opb_free_mod = (*rye) -> rye_param_mod;
403#else
404 op2 -> opb_free = (*rye) -> rye_param_free;
405#endif
406 }
407 else {
408 if (roe -> roe_param) {
409 result = ROS_REP_MISTYPED;
410 goto bad_error;
411 }
412
413 result = OK;
414 }
415
416 op2 -> opb_pe = roe -> roe_param, roe -> roe_param = NULLPE;
417 ROEFREE (roe);
418
419 if (result == NOTOK) {
420 result = ROS_REP_MISTYPED;
421 goto bad_response;
422 }
423
424 if (op2 -> opb_errfnx) {
425 result = (*op2 -> opb_errfnx) (sd, op2 -> opb_id,
426 roe -> roe_error,
427 op2 -> opb_out, roi);
428 freeopblk (op2);
429
430 id = roe -> roe_id, cp = "error";
431 goto punch;
432 }
433
434 if (opb == NULLOPB || opb == op2) {
435 if (out == NULL)
436 goto waiting;
437 *out = op2 -> opb_out;
438 op2 -> opb_out = NULL;
439 freeopblk (op2);
440
441 return OK;
442 }
443
444 op2 -> opb_flags |= OPB_EVENT;
445 op2 -> opb_event = *roi; /* struct copy */
446 goto next;
447 }
448
449 case ROI_UREJECT: {
450 register struct RoSAPureject *rou = &roi -> roi_ureject;
451
452 if (rou -> rou_noid)
453 op2 = opb;
454 else
455 if ((op2 = findopblk (sd, rou -> rou_id, OPB_INITIATOR))
456 == NULLOPB
457 || (op2 -> opb_flags & OPB_EVENT))
458 goto next;
459
460 if (op2 -> opb_errfnx) {
461 result = (*op2 -> opb_errfnx) (sd, id = op2 -> opb_id,
462 RY_REJECT,
463 (caddr_t) rou -> rou_reason,
464 roi);
465 freeopblk (op2);
466
467 cp = "reject";
468 goto punch;
469 }
470
471 if (opb == NULLOPB || opb == op2) {
472 freeopblk (op2);
473
474 return OK;
475 }
476
477 op2 -> opb_flags |= OPB_EVENT;
478 op2 -> opb_event = *roi; /* struct copy */
479 goto next;
480 }
481
482 default:
483 return rosaplose (roi, ROS_PROTOCOL, NULLCP,
484 "unknown indication type=%d", roi -> roi_type);
485 }
486
487bad_response: ;
488 {
489 register struct RoSAPureject *rou = &roi -> roi_ureject;
490
491 (void) RoURejectRequest (op2 -> opb_fd, &op2 -> opb_id,
492 result, ROS_NOPRIO, roi);
493
494 roi -> roi_type = ROI_UREJECT;
495 rou -> rou_id = op2 -> opb_id;
496 rou -> rou_noid = 0;
497 rou -> rou_reason = result;
498
499 if (op2 -> opb_errfnx) {
500 result = (*op2 -> opb_errfnx) (sd, id = op2 -> opb_id, RY_REJECT,
501 (caddr_t) rou ->rou_reason, roi);
502
503 freeopblk (op2);
504
505 cp = "reject";
506 goto punch;
507 }
508
509 if (opb == NULLOPB || opb == op2) {
510 freeopblk (op2);
511
512 return OK;
513 }
514
515 op2 -> opb_flags |= OPB_EVENT;
516 op2 -> opb_event = *roi; /* struct copy */
517 }
518 /* and fall... */
519
520next: ;
521 if (secs != NOTOK)
522 return rosaplose (roi, ROS_TIMER, NULLCP, NULLCP);
523
524 switch (result = RoWaitRequest (sd, NOTOK, roi)) {
525 case NOTOK:
526 reason = roi -> roi_preject.rop_reason;
527 if (ROS_FATAL (reason))
528 loseopblk (sd, reason);
529 break;
530
531 case DONE:
532 loseopblk (sd, ROS_IP_RELEASE);
533 break;
534
535 case OK:
536 continue;
537
538 default:
539 result = rosaplose (roi, ROS_PROTOCOL, NULLCP,
540 "unknown return from RoWaitRequest=%d", result);
541 break;
542 }
543
544 return result;
545 }
546}