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